mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge topic 'contour-int-isovalue'
8fc341e71 Allow floating-point isovalues for contours of integer fields Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !3169
This commit is contained in:
commit
974e964920
17
docs/changelog/contour-int-isovalue.md
Normal file
17
docs/changelog/contour-int-isovalue.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Allow floating-point isovalues for contours of integer fields
|
||||||
|
|
||||||
|
The flying edges version of the contouring filter converted the isovalues
|
||||||
|
provided into the same type as the field. This is fine for a floating point
|
||||||
|
field, but for an integer field the isovalue was truncated to the nearest
|
||||||
|
integer.
|
||||||
|
|
||||||
|
This is problematic because it is common to provide a fractional isovalue
|
||||||
|
(usually N + 0.5) for integer fields to avoid degenerate cases of the
|
||||||
|
contour intersecting vertices. It also means the behavior changes between
|
||||||
|
an integer type that is directly supported (like a `signed char`) or an
|
||||||
|
integer type that is not directly supported and converted to a floating
|
||||||
|
point field (like potentially a `char`).
|
||||||
|
|
||||||
|
This change updates the worklets to allow the isovalue to have a different
|
||||||
|
type than the field and to always use a floating point type for the
|
||||||
|
isovalue.
|
@ -63,10 +63,11 @@ vtkm::cont::DataSet ContourFlyingEdges::DoExecute(const vtkm::cont::DataSet& inD
|
|||||||
auto resolveFieldType = [&](const auto& concrete) {
|
auto resolveFieldType = [&](const auto& concrete) {
|
||||||
// use std::decay to remove const ref from the decltype of concrete.
|
// use std::decay to remove const ref from the decltype of concrete.
|
||||||
using T = typename std::decay_t<decltype(concrete)>::ValueType;
|
using T = typename std::decay_t<decltype(concrete)>::ValueType;
|
||||||
std::vector<T> ivalues(this->IsoValues.size());
|
using IVType = std::conditional_t<(sizeof(T) > 4), vtkm::Float64, vtkm::FloatDefault>;
|
||||||
|
std::vector<IVType> ivalues(this->IsoValues.size());
|
||||||
for (std::size_t i = 0; i < ivalues.size(); ++i)
|
for (std::size_t i = 0; i < ivalues.size(); ++i)
|
||||||
{
|
{
|
||||||
ivalues[i] = static_cast<T>(this->IsoValues[i]);
|
ivalues[i] = static_cast<IVType>(this->IsoValues[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->GenerateNormals && !this->GetComputeFastNormals())
|
if (this->GenerateNormals && !this->GetComputeFastNormals())
|
||||||
|
@ -66,13 +66,14 @@ public:
|
|||||||
void ReleaseCellMapArrays() { this->SharedState.CellIdMap.ReleaseResources(); }
|
void ReleaseCellMapArrays() { this->SharedState.CellIdMap.ReleaseResources(); }
|
||||||
|
|
||||||
// Filter called without normals generation
|
// Filter called without normals generation
|
||||||
template <typename ValueType,
|
template <typename IVType,
|
||||||
|
typename ValueType,
|
||||||
typename CoordsType,
|
typename CoordsType,
|
||||||
typename StorageTagField,
|
typename StorageTagField,
|
||||||
typename CoordinateType,
|
typename CoordinateType,
|
||||||
typename StorageTagVertices>
|
typename StorageTagVertices>
|
||||||
vtkm::cont::CellSetSingleType<> Run(
|
vtkm::cont::CellSetSingleType<> Run(
|
||||||
const std::vector<ValueType>& isovalues,
|
const std::vector<IVType>& isovalues,
|
||||||
const vtkm::cont::CellSetStructured<3>& cells,
|
const vtkm::cont::CellSetStructured<3>& cells,
|
||||||
const CoordsType& coordinateSystem,
|
const CoordsType& coordinateSystem,
|
||||||
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& input,
|
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& input,
|
||||||
@ -87,14 +88,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter called with normals generation
|
// Filter called with normals generation
|
||||||
template <typename ValueType,
|
template <typename IVType,
|
||||||
|
typename ValueType,
|
||||||
typename CoordsType,
|
typename CoordsType,
|
||||||
typename StorageTagField,
|
typename StorageTagField,
|
||||||
typename CoordinateType,
|
typename CoordinateType,
|
||||||
typename StorageTagVertices,
|
typename StorageTagVertices,
|
||||||
typename StorageTagNormals>
|
typename StorageTagNormals>
|
||||||
vtkm::cont::CellSetSingleType<> Run(
|
vtkm::cont::CellSetSingleType<> Run(
|
||||||
const std::vector<ValueType>& isovalues,
|
const std::vector<IVType>& isovalues,
|
||||||
const vtkm::cont::CellSetStructured<3>& cells,
|
const vtkm::cont::CellSetStructured<3>& cells,
|
||||||
const CoordsType& coordinateSystem,
|
const CoordsType& coordinateSystem,
|
||||||
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& input,
|
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& input,
|
||||||
|
@ -40,7 +40,8 @@ vtkm::Id extend_by(vtkm::cont::ArrayHandle<T, S>& handle, vtkm::Id size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
template <typename ValueType,
|
template <typename IVType,
|
||||||
|
typename ValueType,
|
||||||
typename CoordsType,
|
typename CoordsType,
|
||||||
typename StorageTagField,
|
typename StorageTagField,
|
||||||
typename StorageTagVertices,
|
typename StorageTagVertices,
|
||||||
@ -50,7 +51,7 @@ template <typename ValueType,
|
|||||||
vtkm::cont::CellSetSingleType<> execute(
|
vtkm::cont::CellSetSingleType<> execute(
|
||||||
const vtkm::cont::CellSetStructured<3>& cells,
|
const vtkm::cont::CellSetStructured<3>& cells,
|
||||||
const CoordsType coordinateSystem,
|
const CoordsType coordinateSystem,
|
||||||
const std::vector<ValueType>& isovalues,
|
const std::vector<IVType>& isovalues,
|
||||||
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& inputField,
|
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& inputField,
|
||||||
vtkm::cont::ArrayHandle<vtkm::Vec<CoordinateType, 3>, StorageTagVertices>& points,
|
vtkm::cont::ArrayHandle<vtkm::Vec<CoordinateType, 3>, StorageTagVertices>& points,
|
||||||
vtkm::cont::ArrayHandle<vtkm::Vec<NormalType, 3>, StorageTagNormals>& normals,
|
vtkm::cont::ArrayHandle<vtkm::Vec<NormalType, 3>, StorageTagNormals>& normals,
|
||||||
@ -82,7 +83,7 @@ vtkm::cont::CellSetSingleType<> execute(
|
|||||||
{
|
{
|
||||||
auto multiContourCellOffset = sharedState.CellIdMap.GetNumberOfValues();
|
auto multiContourCellOffset = sharedState.CellIdMap.GetNumberOfValues();
|
||||||
auto multiContourPointOffset = sharedState.InterpolationWeights.GetNumberOfValues();
|
auto multiContourPointOffset = sharedState.InterpolationWeights.GetNumberOfValues();
|
||||||
ValueType isoval = isovalues[i];
|
IVType isoval = isovalues[i];
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// PASS 1: Process all of the voxel edges that compose each row. Determine the
|
// PASS 1: Process all of the voxel edges that compose each row. Determine the
|
||||||
@ -100,7 +101,7 @@ vtkm::cont::CellSetSingleType<> execute(
|
|||||||
// Additionally GPU's does significantly better when you do an initial fill
|
// Additionally GPU's does significantly better when you do an initial fill
|
||||||
// and write only non-below values
|
// and write only non-below values
|
||||||
//
|
//
|
||||||
ComputePass1<ValueType> worklet1(isoval, pdims);
|
ComputePass1<IVType> worklet1(isoval, pdims);
|
||||||
vtkm::cont::TryExecuteOnDevice(invoke.GetDevice(),
|
vtkm::cont::TryExecuteOnDevice(invoke.GetDevice(),
|
||||||
launchComputePass1{},
|
launchComputePass1{},
|
||||||
worklet1,
|
worklet1,
|
||||||
|
@ -147,9 +147,13 @@ struct ComputePass1 : public vtkm::worklet::WorkletVisitPointsWithCells
|
|||||||
|
|
||||||
struct launchComputePass1
|
struct launchComputePass1
|
||||||
{
|
{
|
||||||
template <typename DeviceAdapterTag, typename T, typename StorageTagField, typename... Args>
|
template <typename DeviceAdapterTag,
|
||||||
|
typename IVType,
|
||||||
|
typename T,
|
||||||
|
typename StorageTagField,
|
||||||
|
typename... Args>
|
||||||
VTKM_CONT bool LaunchXAxis(DeviceAdapterTag device,
|
VTKM_CONT bool LaunchXAxis(DeviceAdapterTag device,
|
||||||
const ComputePass1<T>& worklet,
|
const ComputePass1<IVType>& worklet,
|
||||||
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
||||||
vtkm::cont::ArrayHandle<vtkm::UInt8>& edgeCases,
|
vtkm::cont::ArrayHandle<vtkm::UInt8>& edgeCases,
|
||||||
vtkm::cont::CellSetStructured<2>& metaDataMesh2D,
|
vtkm::cont::CellSetStructured<2>& metaDataMesh2D,
|
||||||
@ -162,9 +166,13 @@ struct launchComputePass1
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename DeviceAdapterTag, typename T, typename StorageTagField, typename... Args>
|
template <typename DeviceAdapterTag,
|
||||||
|
typename IVType,
|
||||||
|
typename T,
|
||||||
|
typename StorageTagField,
|
||||||
|
typename... Args>
|
||||||
VTKM_CONT bool LaunchYAxis(DeviceAdapterTag device,
|
VTKM_CONT bool LaunchYAxis(DeviceAdapterTag device,
|
||||||
const ComputePass1<T>& worklet,
|
const ComputePass1<IVType>& worklet,
|
||||||
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
||||||
vtkm::cont::ArrayHandle<vtkm::UInt8>& edgeCases,
|
vtkm::cont::ArrayHandle<vtkm::UInt8>& edgeCases,
|
||||||
vtkm::cont::CellSetStructured<2>& metaDataMesh2D,
|
vtkm::cont::CellSetStructured<2>& metaDataMesh2D,
|
||||||
|
@ -42,6 +42,7 @@ struct launchComputePass4
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename DeviceAdapterTag,
|
template <typename DeviceAdapterTag,
|
||||||
|
typename IVType,
|
||||||
typename T,
|
typename T,
|
||||||
typename CoordsType,
|
typename CoordsType,
|
||||||
typename StorageTagField,
|
typename StorageTagField,
|
||||||
@ -50,7 +51,7 @@ struct launchComputePass4
|
|||||||
typename NormalType>
|
typename NormalType>
|
||||||
VTKM_CONT bool LaunchXAxis(DeviceAdapterTag device,
|
VTKM_CONT bool LaunchXAxis(DeviceAdapterTag device,
|
||||||
vtkm::Id vtkmNotUsed(newPointSize),
|
vtkm::Id vtkmNotUsed(newPointSize),
|
||||||
T isoval,
|
IVType isoval,
|
||||||
CoordsType coordinateSystem,
|
CoordsType coordinateSystem,
|
||||||
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
||||||
vtkm::cont::ArrayHandle<vtkm::UInt8> edgeCases,
|
vtkm::cont::ArrayHandle<vtkm::UInt8> edgeCases,
|
||||||
@ -67,7 +68,7 @@ struct launchComputePass4
|
|||||||
vtkm::cont::Invoker invoke(device);
|
vtkm::cont::Invoker invoke(device);
|
||||||
if (sharedState.GenerateNormals)
|
if (sharedState.GenerateNormals)
|
||||||
{
|
{
|
||||||
ComputePass4XWithNormals<T> worklet4(
|
ComputePass4XWithNormals<IVType> worklet4(
|
||||||
isoval, this->PointDims, this->CellWriteOffset, this->PointWriteOffset);
|
isoval, this->PointDims, this->CellWriteOffset, this->PointWriteOffset);
|
||||||
invoke(worklet4,
|
invoke(worklet4,
|
||||||
metaDataMesh2D,
|
metaDataMesh2D,
|
||||||
@ -87,7 +88,7 @@ struct launchComputePass4
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ComputePass4X<T> worklet4(
|
ComputePass4X<IVType> worklet4(
|
||||||
isoval, this->PointDims, this->CellWriteOffset, this->PointWriteOffset);
|
isoval, this->PointDims, this->CellWriteOffset, this->PointWriteOffset);
|
||||||
invoke(worklet4,
|
invoke(worklet4,
|
||||||
metaDataMesh2D,
|
metaDataMesh2D,
|
||||||
@ -109,6 +110,7 @@ struct launchComputePass4
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename DeviceAdapterTag,
|
template <typename DeviceAdapterTag,
|
||||||
|
typename IVType,
|
||||||
typename T,
|
typename T,
|
||||||
typename CoordsType,
|
typename CoordsType,
|
||||||
typename StorageTagField,
|
typename StorageTagField,
|
||||||
@ -117,7 +119,7 @@ struct launchComputePass4
|
|||||||
typename NormalType>
|
typename NormalType>
|
||||||
VTKM_CONT bool LaunchYAxis(DeviceAdapterTag device,
|
VTKM_CONT bool LaunchYAxis(DeviceAdapterTag device,
|
||||||
vtkm::Id newPointSize,
|
vtkm::Id newPointSize,
|
||||||
T isoval,
|
IVType isoval,
|
||||||
CoordsType coordinateSystem,
|
CoordsType coordinateSystem,
|
||||||
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
||||||
vtkm::cont::ArrayHandle<vtkm::UInt8> edgeCases,
|
vtkm::cont::ArrayHandle<vtkm::UInt8> edgeCases,
|
||||||
@ -133,7 +135,7 @@ struct launchComputePass4
|
|||||||
{
|
{
|
||||||
vtkm::cont::Invoker invoke(device);
|
vtkm::cont::Invoker invoke(device);
|
||||||
|
|
||||||
ComputePass4Y<T> worklet4(
|
ComputePass4Y<IVType> worklet4(
|
||||||
isoval, this->PointDims, this->CellWriteOffset, this->PointWriteOffset);
|
isoval, this->PointDims, this->CellWriteOffset, this->PointWriteOffset);
|
||||||
invoke(worklet4,
|
invoke(worklet4,
|
||||||
metaDataMesh2D,
|
metaDataMesh2D,
|
||||||
@ -149,7 +151,8 @@ struct launchComputePass4
|
|||||||
sharedState.CellIdMap);
|
sharedState.CellIdMap);
|
||||||
|
|
||||||
//This needs to be done on array handle view ( start = this->PointWriteOffset, len = newPointSize)
|
//This needs to be done on array handle view ( start = this->PointWriteOffset, len = newPointSize)
|
||||||
ComputePass5Y<T> worklet5(this->PointDims, this->PointWriteOffset, sharedState.GenerateNormals);
|
ComputePass5Y<IVType> worklet5(
|
||||||
|
this->PointDims, this->PointWriteOffset, sharedState.GenerateNormals);
|
||||||
|
|
||||||
invoke(worklet5,
|
invoke(worklet5,
|
||||||
vtkm::cont::make_ArrayHandleView(
|
vtkm::cont::make_ArrayHandleView(
|
||||||
|
Loading…
Reference in New Issue
Block a user