mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge branch 'master' into rendering_cpp_cleanup
This commit is contained in:
commit
ee9c78ca94
@ -10,16 +10,31 @@
|
||||
##
|
||||
##=============================================================================
|
||||
|
||||
# Find the path the logs from the last configure
|
||||
set(configure_warning_exceptions
|
||||
".*CMake Warning at CMake/VTKmDetermineVersion.cmake.*"
|
||||
)
|
||||
|
||||
# Find the path of the logs from the last configure
|
||||
set(cnf_log_path "${CMAKE_SOURCE_DIR}/build/Testing/Temporary/LastConfigure*.log")
|
||||
file(GLOB cnf_log_files ${cnf_log_path})
|
||||
|
||||
# Check for warnings during the configure phase
|
||||
foreach(file IN LISTS cnf_log_files)
|
||||
file(STRINGS ${file} lines)
|
||||
string(FIND "${lines}" "Warning" line)
|
||||
if (NOT ${line} EQUAL "-1")
|
||||
message(FATAL_ERROR "Configure warnings detected, please check cdash-commit job")
|
||||
endif()
|
||||
foreach(line IN LISTS lines)
|
||||
if ("${line}" MATCHES "Warning|WARNING|warning")
|
||||
set(exception_matches FALSE)
|
||||
foreach(exception IN LISTS configure_warning_exceptions)
|
||||
if (${line} MATCHES "${exception}")
|
||||
set(exception_matches TRUE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
if (NOT exception_matches)
|
||||
message(FATAL_ERROR "Configure warnings detected, please check cdash-commit job: ${line}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
# `compile_num_warnings` contains a single integer symbolizing the number of
|
||||
|
@ -156,6 +156,25 @@ foreach(option IN LISTS options)
|
||||
|
||||
endforeach()
|
||||
|
||||
# We need to use VTKm_CUDA_Architecture for older CMake versions
|
||||
if(vtkm_cuda_arch)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
|
||||
if(vtkm_cuda_arch STREQUAL "maxwell")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "50" CACHE STRING "")
|
||||
elseif(vtkm_cuda_arch STREQUAL "pascal")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "60" CACHE STRING "")
|
||||
elseif(vtkm_cuda_arch STREQUAL "volta")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "70" CACHE STRING "")
|
||||
elseif(vtkm_cuda_arch STREQUAL "turing")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "75" CACHE STRING "")
|
||||
elseif(vtkm_cuda_arch STREQUAL "ampere")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "80" CACHE STRING "")
|
||||
endif()
|
||||
else()
|
||||
set(VTKm_CUDA_Architecture "${vtkm_cuda_arch}" CACHE STRING "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Compile tutorials on all builders. The code is small and basic. And since
|
||||
# it is the tutorial, it should work really well.
|
||||
set(VTKm_ENABLE_TUTORIALS "ON" CACHE STRING "")
|
||||
@ -181,22 +200,3 @@ endif()
|
||||
if(sanitizers)
|
||||
set(VTKm_USE_SANITIZER "${sanitizers}" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
# We need to use VTKm_CUDA_Architecture for older CMake versions
|
||||
if(vtkm_cuda_arch)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
|
||||
if(vtkm_cuda_arch STREQUAL "maxwell")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "50" CACHE STRING "")
|
||||
elseif(vtkm_cuda_arch STREQUAL "pascal")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "60" CACHE STRING "")
|
||||
elseif(vtkm_cuda_arch STREQUAL "volta")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "70" CACHE STRING "")
|
||||
elseif(vtkm_cuda_arch STREQUAL "turing")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "75" CACHE STRING "")
|
||||
elseif(vtkm_cuda_arch STREQUAL "ampere")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "80" CACHE STRING "")
|
||||
endif()
|
||||
else()
|
||||
set(VTKm_CUDA_Architecture "${vtkm_cuda_arch}" CACHE STRING "")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -438,8 +438,7 @@ void BenchContour(::benchmark::State& state)
|
||||
|
||||
filter.SetMergeDuplicatePoints(mergePoints);
|
||||
filter.SetGenerateNormals(normals);
|
||||
filter.SetComputeFastNormalsForStructured(fastNormals);
|
||||
filter.SetComputeFastNormalsForUnstructured(fastNormals);
|
||||
filter.SetComputeFastNormals(fastNormals);
|
||||
|
||||
vtkm::cont::Timer timer{ device };
|
||||
|
||||
|
@ -340,8 +340,7 @@ void BenchContour(::benchmark::State& state)
|
||||
filter.SetActiveField(PointScalarsName, vtkm::cont::Field::Association::Points);
|
||||
filter.SetMergeDuplicatePoints(true);
|
||||
filter.SetGenerateNormals(true);
|
||||
filter.SetComputeFastNormalsForStructured(true);
|
||||
filter.SetComputeFastNormalsForUnstructured(true);
|
||||
filter.SetComputeFastNormals(true);
|
||||
state.ResumeTiming(); // And resume timers.
|
||||
|
||||
filterTimer.Start();
|
||||
|
5
docs/changelog/flying-edges-structured.md
Normal file
5
docs/changelog/flying-edges-structured.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Implement Flying Edges for structured cellsets with rectilinear and curvilinear coordinates
|
||||
|
||||
When Flying Edges was introduced to compute contours of a 3D structured cellset, it could only process uniform coordinates. This limitation is now lifted : an alternative interpolation function can be used in the fourth pass of the algorithm in order to support rectilinear and curvilinear coordinate systems.
|
||||
|
||||
Accordingly, the `Contour` filter now calls `ContourFlyingEdges` instead of `ContourMarchingCells` for these newly supported cases.
|
11
docs/changelog/split-contour-filters.md
Normal file
11
docs/changelog/split-contour-filters.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Split flying edges and marching cells into separate filters
|
||||
|
||||
The contour filter contains 2 separate implementations, Marching Cells and Flying Edges, the latter only available if the input has a `CellSetStructured<3>` and `ArrayHandleUniformPointCoordinates` for point coordinates. The compilation of this filter was lenghty and resource-heavy, because both algorithms were part of the same translation unit.
|
||||
|
||||
Now, this filter is separated into two new filters, `ContourFlyingEdges` and `ContourMarchingCells`, compiling more efficiently into two translation units. The `Contour` API is left unchanged. All 3 filters `Contour`, `ContourFlyingEdges` and `ContourMarchingCells` rely on a new abstract class `AbstractContour` to provide configuration and common utility functions.
|
||||
|
||||
Although `Contour` is still the preferred option for most cases because it selects the best implementation according to the input, `ContourMarchingCells` is usable on any kind of 3D Dataset. For now, `ContourFlyingEdges` operates only on structured uniform datasets.
|
||||
|
||||
Deprecate functions `GetComputeFastNormalsForStructured`, `SetComputeFastNormalsForStructured`, `GetComputeFastNormalsForUnstructured` and `GetComputeFastNormalsForUnstructured`, to use the more general `GetComputeFastNormals` and `SetComputeFastNormals` instead.
|
||||
|
||||
By default, for the `Contour` filter, `GenerateNormals` is now `true`, and `ComputeFastNormals` is `false`.
|
8
docs/changelog/unknown-runtime-vec-new-instance.md
Normal file
8
docs/changelog/unknown-runtime-vec-new-instance.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Fix new instances of ArrayHandleRuntimeVec in UnknownArrayHandle
|
||||
|
||||
`UnknownArrayHandle` is supposed to treat `ArrayHandleRuntimeVec` the same
|
||||
as `ArrayHandleBasic`. However, the `NewInstance` methods were failing
|
||||
because they need custom handling of the vec size. Special cases in the
|
||||
`UnknownArrayHandle::NewInstance*()` methods have been added to fix this
|
||||
problem.
|
||||
|
@ -177,6 +177,16 @@ VTKM_CONT bool UnknownArrayHandle::IsValid() const
|
||||
|
||||
VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstance() const
|
||||
{
|
||||
if (this->IsStorageType<vtkm::cont::StorageTagRuntimeVec>())
|
||||
{
|
||||
// Special case for `ArrayHandleRuntimeVec`, which (1) can be used in place of
|
||||
// a basic array in `UnknownArrayHandle` and (2) needs a special construction to
|
||||
// capture the correct number of components. Also note that we are allowing this
|
||||
// special case to be implemented in `NewInstanceBasic` because it has a better
|
||||
// fallback (throw an exception rather than create a potentially incompatible
|
||||
// with the wrong number of components).
|
||||
return this->NewInstanceBasic();
|
||||
}
|
||||
UnknownArrayHandle newArray;
|
||||
if (this->Container)
|
||||
{
|
||||
@ -188,6 +198,25 @@ VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstance() const
|
||||
VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceBasic() const
|
||||
{
|
||||
UnknownArrayHandle newArray;
|
||||
if (this->IsStorageType<vtkm::cont::StorageTagRuntimeVec>())
|
||||
{
|
||||
// Special case for `ArrayHandleRuntimeVec`, which (1) can be used in place of
|
||||
// a basic array in `UnknownArrayHandle` and (2) needs a special construction to
|
||||
// capture the correct number of components.
|
||||
auto runtimeVecArrayCreator = [&](auto exampleComponent) {
|
||||
using ComponentType = decltype(exampleComponent);
|
||||
if (this->IsBaseComponentType<ComponentType>())
|
||||
{
|
||||
newArray =
|
||||
vtkm::cont::make_ArrayHandleRuntimeVec<ComponentType>(this->GetNumberOfComponentsFlat());
|
||||
}
|
||||
};
|
||||
vtkm::ListForEach(runtimeVecArrayCreator, vtkm::TypeListBaseC{});
|
||||
if (newArray.IsValid())
|
||||
{
|
||||
return newArray;
|
||||
}
|
||||
}
|
||||
if (this->Container)
|
||||
{
|
||||
newArray.Container = this->Container->NewInstanceBasic();
|
||||
@ -197,6 +226,14 @@ VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceBasic() const
|
||||
|
||||
VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceFloatBasic() const
|
||||
{
|
||||
if (this->IsStorageType<vtkm::cont::StorageTagRuntimeVec>())
|
||||
{
|
||||
// Special case for `ArrayHandleRuntimeVec`, which (1) can be used in place of
|
||||
// a basic array in `UnknownArrayHandle` and (2) needs a special construction to
|
||||
// capture the correct number of components.
|
||||
return vtkm::cont::make_ArrayHandleRuntimeVec<vtkm::FloatDefault>(
|
||||
this->GetNumberOfComponentsFlat());
|
||||
}
|
||||
UnknownArrayHandle newArray;
|
||||
if (this->Container)
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <vtkm/cont/UncertainArrayHandle.h>
|
||||
#include <vtkm/cont/UnknownArrayHandle.h>
|
||||
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
@ -574,6 +575,27 @@ void TryConvertRuntimeVec()
|
||||
VTKM_TEST_ASSERT(unknownWithRuntimeVec.CanConvert<BasicArrayType>());
|
||||
BasicArrayType outputArray = unknownWithRuntimeVec.AsArrayHandle<BasicArrayType>();
|
||||
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, outputArray));
|
||||
|
||||
std::cout << " Copy ArrayHandleRuntimeVec to a new instance" << std::endl;
|
||||
vtkm::cont::UnknownArrayHandle unknownCopy = unknownWithRuntimeVec.NewInstance();
|
||||
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
|
||||
unknownCopy.GetNumberOfComponentsFlat());
|
||||
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
|
||||
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
|
||||
|
||||
std::cout << " Copy ArrayHandleRuntimeVec as basic array" << std::endl;
|
||||
unknownCopy = unknownWithRuntimeVec.NewInstanceBasic();
|
||||
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
|
||||
unknownCopy.GetNumberOfComponentsFlat());
|
||||
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
|
||||
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
|
||||
|
||||
std::cout << " Copy ArrayHandleRuntimeVec to float array" << std::endl;
|
||||
unknownCopy = unknownWithRuntimeVec.NewInstanceFloatBasic();
|
||||
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
|
||||
unknownCopy.GetNumberOfComponentsFlat());
|
||||
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
|
||||
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
|
||||
}
|
||||
|
||||
void TryConvertRuntimeVec()
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
#include <vtkm/filter/contour/Contour.h>
|
||||
#include <vtkm/filter/contour/ContourMarchingCells.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -72,13 +72,7 @@ void TestPointMerging()
|
||||
vtkm::cont::testing::MakeTestDataSet makeDataSet;
|
||||
vtkm::cont::DataSet baseData = makeDataSet.Make3DUniformDataSet3(vtkm::Id3(4, 4, 4));
|
||||
|
||||
//Convert the baseData implicit points to explicit points, since the contour
|
||||
//filter for uniform data always does point merging
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> newcoords;
|
||||
vtkm::cont::ArrayCopy(baseData.GetCoordinateSystem().GetData(), newcoords);
|
||||
baseData.AddPointField(baseData.GetCoordinateSystemName(), newcoords);
|
||||
|
||||
vtkm::filter::contour::Contour marchingCubes;
|
||||
vtkm::filter::contour::ContourMarchingCells marchingCubes;
|
||||
marchingCubes.SetIsoValue(0.05);
|
||||
marchingCubes.SetMergeDuplicatePoints(false);
|
||||
marchingCubes.SetActiveField("pointvar");
|
||||
|
181
vtkm/filter/contour/AbstractContour.h
Normal file
181
vtkm/filter/contour/AbstractContour.h
Normal file
@ -0,0 +1,181 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_filter_contour_AbstractContour_h
|
||||
#define vtk_m_filter_contour_AbstractContour_h
|
||||
|
||||
#include <vtkm/filter/FilterField.h>
|
||||
#include <vtkm/filter/MapFieldPermutation.h>
|
||||
#include <vtkm/filter/contour/vtkm_filter_contour_export.h>
|
||||
#include <vtkm/filter/vector_analysis/SurfaceNormals.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
namespace contour
|
||||
{
|
||||
/// \brief Contour filter interface
|
||||
///
|
||||
/// Provides common configuration & execution methods for contour filters
|
||||
/// Only the method \c DoExecute executing the contour algorithm needs to be implemented
|
||||
class VTKM_FILTER_CONTOUR_EXPORT AbstractContour : public vtkm::filter::FilterField
|
||||
{
|
||||
public:
|
||||
void SetNumberOfIsoValues(vtkm::Id num)
|
||||
{
|
||||
if (num >= 0)
|
||||
{
|
||||
this->IsoValues.resize(static_cast<std::size_t>(num));
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::Id GetNumberOfIsoValues() const { return static_cast<vtkm::Id>(this->IsoValues.size()); }
|
||||
|
||||
void SetIsoValue(vtkm::Float64 v) { this->SetIsoValue(0, v); }
|
||||
|
||||
void SetIsoValue(vtkm::Id index, vtkm::Float64 v)
|
||||
{
|
||||
std::size_t i = static_cast<std::size_t>(index);
|
||||
if (i >= this->IsoValues.size())
|
||||
{
|
||||
this->IsoValues.resize(i + 1);
|
||||
}
|
||||
this->IsoValues[i] = v;
|
||||
}
|
||||
|
||||
void SetIsoValues(const std::vector<vtkm::Float64>& values) { this->IsoValues = values; }
|
||||
|
||||
vtkm::Float64 GetIsoValue(vtkm::Id index) const
|
||||
{
|
||||
return this->IsoValues[static_cast<std::size_t>(index)];
|
||||
}
|
||||
|
||||
/// Set/Get whether normals should be generated. Off by default.
|
||||
VTKM_CONT
|
||||
void SetGenerateNormals(bool on) { this->GenerateNormals = on; }
|
||||
VTKM_CONT
|
||||
bool GetGenerateNormals() const { return this->GenerateNormals; }
|
||||
|
||||
/// Set/Get whether to append the ids of the intersected edges to the vertices of the isosurface triangles. Off by default.
|
||||
VTKM_CONT
|
||||
void SetAddInterpolationEdgeIds(bool on) { this->AddInterpolationEdgeIds = on; }
|
||||
VTKM_CONT
|
||||
bool GetAddInterpolationEdgeIds() const { return this->AddInterpolationEdgeIds; }
|
||||
|
||||
/// Set/Get whether the fast path should be used for normals computation. Off by default.
|
||||
VTKM_CONT
|
||||
void SetComputeFastNormals(bool on) { this->ComputeFastNormals = on; }
|
||||
VTKM_CONT
|
||||
bool GetComputeFastNormals() const { return this->ComputeFastNormals; }
|
||||
|
||||
VTKM_CONT
|
||||
void SetNormalArrayName(const std::string& name) { this->NormalArrayName = name; }
|
||||
|
||||
VTKM_CONT
|
||||
const std::string& GetNormalArrayName() const { return this->NormalArrayName; }
|
||||
|
||||
/// Set/Get whether the points generated should be unique for every triangle
|
||||
/// or will duplicate points be merged together. Duplicate points are identified
|
||||
/// by the unique edge it was generated from.
|
||||
///
|
||||
VTKM_CONT
|
||||
void SetMergeDuplicatePoints(bool on) { this->MergeDuplicatedPoints = on; }
|
||||
|
||||
VTKM_CONT
|
||||
bool GetMergeDuplicatePoints() { return this->MergeDuplicatedPoints; }
|
||||
|
||||
protected:
|
||||
/// \brief Map a given field to the output \c DataSet , depending on its type.
|
||||
///
|
||||
/// The worklet needs to implement \c ProcessPointField to process point fields as arrays
|
||||
/// and \c GetCellIdMap function giving the cell id mapping from input to output
|
||||
template <typename WorkletType>
|
||||
VTKM_CONT static bool DoMapField(vtkm::cont::DataSet& result,
|
||||
const vtkm::cont::Field& field,
|
||||
WorkletType& worklet)
|
||||
{
|
||||
if (field.IsPointField())
|
||||
{
|
||||
vtkm::cont::UnknownArrayHandle inputArray = field.GetData();
|
||||
vtkm::cont::UnknownArrayHandle outputArray = inputArray.NewInstanceBasic();
|
||||
|
||||
auto functor = [&](const auto& concrete) {
|
||||
using ComponentType = typename std::decay_t<decltype(concrete)>::ValueType::ComponentType;
|
||||
auto fieldArray = outputArray.ExtractArrayFromComponents<ComponentType>();
|
||||
worklet.ProcessPointField(concrete, fieldArray);
|
||||
};
|
||||
inputArray.CastAndCallWithExtractedArray(functor);
|
||||
result.AddPointField(field.GetName(), outputArray);
|
||||
return true;
|
||||
}
|
||||
else if (field.IsCellField())
|
||||
{
|
||||
// Use the precompiled field permutation function.
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> permutation = worklet.GetCellIdMap();
|
||||
return vtkm::filter::MapFieldPermutation(field, permutation, result);
|
||||
}
|
||||
else if (field.IsWholeDataSetField())
|
||||
{
|
||||
result.AddField(field);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VTKM_CONT void ExecuteGenerateNormals(vtkm::cont::DataSet& output,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec3f>& normals)
|
||||
{
|
||||
if (this->GenerateNormals)
|
||||
{
|
||||
if (this->GetComputeFastNormals())
|
||||
{
|
||||
vtkm::filter::vector_analysis::SurfaceNormals surfaceNormals;
|
||||
surfaceNormals.SetPointNormalsName(this->NormalArrayName);
|
||||
surfaceNormals.SetGeneratePointNormals(true);
|
||||
output = surfaceNormals.Execute(output);
|
||||
}
|
||||
else
|
||||
{
|
||||
output.AddField(vtkm::cont::make_FieldPoint(this->NormalArrayName, normals));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename WorkletType>
|
||||
VTKM_CONT void ExecuteAddInterpolationEdgeIds(vtkm::cont::DataSet& output, WorkletType& worklet)
|
||||
{
|
||||
if (this->AddInterpolationEdgeIds)
|
||||
{
|
||||
vtkm::cont::Field interpolationEdgeIdsField(this->InterpolationEdgeIdsArrayName,
|
||||
vtkm::cont::Field::Association::Points,
|
||||
worklet.GetInterpolationEdgeIds());
|
||||
output.AddField(interpolationEdgeIdsField);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
virtual vtkm::cont::DataSet DoExecute(
|
||||
const vtkm::cont::DataSet& result) = 0; // Needs to be overridden by contour implementations
|
||||
|
||||
std::vector<vtkm::Float64> IsoValues;
|
||||
bool GenerateNormals = true;
|
||||
bool ComputeFastNormals = false;
|
||||
|
||||
bool AddInterpolationEdgeIds = false;
|
||||
bool MergeDuplicatedPoints = true;
|
||||
std::string NormalArrayName = "normals";
|
||||
std::string InterpolationEdgeIdsArrayName = "edgeIds";
|
||||
};
|
||||
} // namespace contour
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
||||
|
||||
#endif // vtk_m_filter_contour_AbstractContour_h
|
@ -9,9 +9,12 @@
|
||||
##============================================================================
|
||||
|
||||
set(contour_headers
|
||||
AbstractContour.h
|
||||
ClipWithField.h
|
||||
ClipWithImplicitFunction.h
|
||||
Contour.h
|
||||
ContourFlyingEdges.h
|
||||
ContourMarchingCells.h
|
||||
MIRFilter.h
|
||||
Slice.h
|
||||
)
|
||||
@ -19,15 +22,23 @@ set(contour_headers
|
||||
set(contour_sources_device
|
||||
ClipWithField.cxx
|
||||
ClipWithImplicitFunction.cxx
|
||||
Contour.cxx
|
||||
ContourFlyingEdges.cxx
|
||||
ContourMarchingCells.cxx
|
||||
MIRFilter.cxx
|
||||
Slice.cxx
|
||||
)
|
||||
|
||||
set(contour_sources
|
||||
# Contour defers worklet compilation to other filters,
|
||||
# so it does not need to be compiled with a device adapter.
|
||||
Contour.cxx
|
||||
)
|
||||
|
||||
set_source_files_properties(Contour.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
|
||||
|
||||
vtkm_library(
|
||||
NAME vtkm_filter_contour
|
||||
SOURCES ${contour_sources}
|
||||
HEADERS ${contour_headers}
|
||||
DEVICE_SOURCES ${contour_sources_device}
|
||||
USE_VTKM_JOB_POOL
|
||||
|
@ -7,16 +7,13 @@
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/CellSetSingleType.h>
|
||||
#include <vtkm/cont/CellSetStructured.h>
|
||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||
#include <vtkm/cont/UnknownCellSet.h>
|
||||
|
||||
#include <vtkm/filter/MapFieldPermutation.h>
|
||||
#include <vtkm/filter/contour/Contour.h>
|
||||
#include <vtkm/filter/contour/worklet/Contour.h>
|
||||
#include <vtkm/filter/vector_analysis/SurfaceNormals.h>
|
||||
#include <vtkm/filter/contour/ContourFlyingEdges.h>
|
||||
#include <vtkm/filter/contour/ContourMarchingCells.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -25,155 +22,45 @@ namespace filter
|
||||
|
||||
using SupportedTypes = vtkm::List<vtkm::UInt8, vtkm::Int8, vtkm::Float32, vtkm::Float64>;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
inline bool IsCellSetStructured(const vtkm::cont::UnknownCellSet& cellset)
|
||||
{
|
||||
if (cellset.template IsType<vtkm::cont::CellSetStructured<1>>() ||
|
||||
cellset.template IsType<vtkm::cont::CellSetStructured<2>>() ||
|
||||
cellset.template IsType<vtkm::cont::CellSetStructured<3>>())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
|
||||
const vtkm::cont::Field& field,
|
||||
vtkm::worklet::Contour& worklet)
|
||||
{
|
||||
if (field.IsPointField())
|
||||
{
|
||||
vtkm::cont::UnknownArrayHandle inputArray = field.GetData();
|
||||
vtkm::cont::UnknownArrayHandle outputArray = inputArray.NewInstanceBasic();
|
||||
|
||||
auto functor = [&](const auto& concrete) {
|
||||
using ComponentType = typename std::decay_t<decltype(concrete)>::ValueType::ComponentType;
|
||||
auto fieldArray = outputArray.ExtractArrayFromComponents<ComponentType>();
|
||||
worklet.ProcessPointField(concrete, fieldArray);
|
||||
};
|
||||
inputArray.CastAndCallWithExtractedArray(functor);
|
||||
result.AddPointField(field.GetName(), outputArray);
|
||||
return true;
|
||||
}
|
||||
else if (field.IsCellField())
|
||||
{
|
||||
// Use the precompiled field permutation function.
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> permutation = worklet.GetCellIdMap();
|
||||
return vtkm::filter::MapFieldPermutation(field, permutation, result);
|
||||
}
|
||||
else if (field.IsWholeDataSetField())
|
||||
{
|
||||
result.AddField(field);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace contour
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
void Contour::SetMergeDuplicatePoints(bool on)
|
||||
{
|
||||
this->MergeDuplicatedPoints = on;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
bool Contour::GetMergeDuplicatePoints() const
|
||||
{
|
||||
return MergeDuplicatedPoints;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
vtkm::cont::DataSet Contour::DoExecute(const vtkm::cont::DataSet& inDataSet)
|
||||
{
|
||||
vtkm::worklet::Contour worklet;
|
||||
worklet.SetMergeDuplicatePoints(this->GetMergeDuplicatePoints());
|
||||
// Switch between Marching Cubes and Flying Edges implementation of contour,
|
||||
// depending on the type of CellSet we are processing
|
||||
|
||||
if (!this->GetFieldFromDataSet(inDataSet).IsPointField())
|
||||
vtkm::cont::UnknownCellSet inCellSet = inDataSet.GetCellSet();
|
||||
auto inCoords = inDataSet.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()).GetData();
|
||||
std::unique_ptr<vtkm::filter::contour::AbstractContour> implementation;
|
||||
|
||||
// Flying Edges is only used for 3D Structured CellSets
|
||||
if (inCellSet.template IsType<vtkm::cont::CellSetStructured<3>>())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution("Point field expected.");
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Using flying edges");
|
||||
implementation.reset(new vtkm::filter::contour::ContourFlyingEdges);
|
||||
implementation->SetComputeFastNormals(this->GetComputeFastNormals());
|
||||
}
|
||||
else
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Using marching cells");
|
||||
implementation.reset(new vtkm::filter::contour::ContourMarchingCells);
|
||||
implementation->SetComputeFastNormals(this->GetComputeFastNormals());
|
||||
}
|
||||
|
||||
if (this->IsoValues.empty())
|
||||
implementation->SetMergeDuplicatePoints(this->GetMergeDuplicatePoints());
|
||||
implementation->SetGenerateNormals(this->GetGenerateNormals());
|
||||
implementation->SetAddInterpolationEdgeIds(this->GetAddInterpolationEdgeIds());
|
||||
implementation->SetNormalArrayName(this->GetNormalArrayName());
|
||||
implementation->SetActiveField(this->GetActiveFieldName());
|
||||
implementation->SetFieldsToPass(this->GetFieldsToPass());
|
||||
implementation->SetNumberOfIsoValues(this->GetNumberOfIsoValues());
|
||||
for (int i = 0; i < this->GetNumberOfIsoValues(); i++)
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution("No iso-values provided.");
|
||||
implementation->SetIsoValue(i, this->GetIsoValue(i));
|
||||
}
|
||||
|
||||
//get the inputCells and coordinates of the dataset
|
||||
const vtkm::cont::UnknownCellSet& inputCells = inDataSet.GetCellSet();
|
||||
const vtkm::cont::CoordinateSystem& inputCoords =
|
||||
inDataSet.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex());
|
||||
|
||||
using Vec3HandleType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
|
||||
Vec3HandleType vertices;
|
||||
Vec3HandleType normals;
|
||||
|
||||
vtkm::cont::CellSetSingleType<> outputCells;
|
||||
|
||||
bool generateHighQualityNormals = IsCellSetStructured(inputCells)
|
||||
? !this->ComputeFastNormalsForStructured
|
||||
: !this->ComputeFastNormalsForUnstructured;
|
||||
|
||||
auto resolveFieldType = [&](const auto& concrete) {
|
||||
// use std::decay to remove const ref from the decltype of concrete.
|
||||
using T = typename std::decay_t<decltype(concrete)>::ValueType;
|
||||
std::vector<T> ivalues(this->IsoValues.size());
|
||||
for (std::size_t i = 0; i < ivalues.size(); ++i)
|
||||
{
|
||||
ivalues[i] = static_cast<T>(this->IsoValues[i]);
|
||||
}
|
||||
|
||||
if (this->GenerateNormals && generateHighQualityNormals)
|
||||
{
|
||||
outputCells =
|
||||
worklet.Run(ivalues, inputCells, inputCoords.GetData(), concrete, vertices, normals);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputCells = worklet.Run(ivalues, inputCells, inputCoords.GetData(), concrete, vertices);
|
||||
}
|
||||
};
|
||||
|
||||
this->GetFieldFromDataSet(inDataSet)
|
||||
.GetData()
|
||||
.CastAndCallForTypesWithFloatFallback<SupportedTypes, VTKM_DEFAULT_STORAGE_LIST>(
|
||||
resolveFieldType);
|
||||
|
||||
auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); };
|
||||
vtkm::cont::DataSet output = this->CreateResultCoordinateSystem(
|
||||
inDataSet, outputCells, inputCoords.GetName(), vertices, mapper);
|
||||
|
||||
if (this->GenerateNormals)
|
||||
{
|
||||
if (!generateHighQualityNormals)
|
||||
{
|
||||
vtkm::filter::vector_analysis::SurfaceNormals surfaceNormals;
|
||||
surfaceNormals.SetPointNormalsName(this->NormalArrayName);
|
||||
surfaceNormals.SetGeneratePointNormals(true);
|
||||
output = surfaceNormals.Execute(output);
|
||||
}
|
||||
else
|
||||
{
|
||||
output.AddField(vtkm::cont::make_FieldPoint(this->NormalArrayName, normals));
|
||||
}
|
||||
}
|
||||
|
||||
if (this->AddInterpolationEdgeIds)
|
||||
{
|
||||
vtkm::cont::Field interpolationEdgeIdsField(InterpolationEdgeIdsArrayName,
|
||||
vtkm::cont::Field::Association::Points,
|
||||
worklet.GetInterpolationEdgeIds());
|
||||
output.AddField(interpolationEdgeIdsField);
|
||||
}
|
||||
|
||||
return output;
|
||||
return implementation->Execute(inDataSet);
|
||||
}
|
||||
} // namespace contour
|
||||
} // namespace filter
|
||||
|
@ -11,7 +11,7 @@
|
||||
#ifndef vtk_m_filter_contour_Contour_h
|
||||
#define vtk_m_filter_contour_Contour_h
|
||||
|
||||
#include <vtkm/filter/FilterField.h>
|
||||
#include <vtkm/filter/contour/AbstractContour.h>
|
||||
#include <vtkm/filter/contour/vtkm_filter_contour_export.h>
|
||||
|
||||
namespace vtkm
|
||||
@ -25,103 +25,33 @@ namespace contour
|
||||
/// Takes as input a volume (e.g., 3D structured point set) and generates on
|
||||
/// output one or more isosurfaces.
|
||||
/// Multiple contour values must be specified to generate the isosurfaces.
|
||||
/// This filter automatically selects the right implmentation between Marching Cells
|
||||
/// and Flying Edges algorithms depending on the type of input \c DataSet : Flying Edges
|
||||
/// is only available for 3-dimensional datasets using uniform point coordinates.
|
||||
/// @warning
|
||||
/// This filter is currently only supports 3D volumes.
|
||||
class VTKM_FILTER_CONTOUR_EXPORT Contour : public vtkm::filter::FilterField
|
||||
class VTKM_FILTER_CONTOUR_EXPORT Contour : public vtkm::filter::contour::AbstractContour
|
||||
{
|
||||
public:
|
||||
void SetNumberOfIsoValues(vtkm::Id num)
|
||||
{
|
||||
if (num >= 0)
|
||||
{
|
||||
this->IsoValues.resize(static_cast<std::size_t>(num));
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::Id GetNumberOfIsoValues() const { return static_cast<vtkm::Id>(this->IsoValues.size()); }
|
||||
|
||||
void SetIsoValue(vtkm::Float64 v) { this->SetIsoValue(0, v); }
|
||||
|
||||
void SetIsoValue(vtkm::Id index, vtkm::Float64 v)
|
||||
{
|
||||
std::size_t i = static_cast<std::size_t>(index);
|
||||
if (i >= this->IsoValues.size())
|
||||
{
|
||||
this->IsoValues.resize(i + 1);
|
||||
}
|
||||
this->IsoValues[i] = v;
|
||||
}
|
||||
|
||||
void SetIsoValues(const std::vector<vtkm::Float64>& values) { this->IsoValues = values; }
|
||||
|
||||
vtkm::Float64 GetIsoValue(vtkm::Id index) const
|
||||
{
|
||||
return this->IsoValues[static_cast<std::size_t>(index)];
|
||||
}
|
||||
|
||||
/// Set/Get whether the points generated should be unique for every triangle
|
||||
/// or will duplicate points be merged together. Duplicate points are identified
|
||||
/// by the unique edge it was generated from.
|
||||
///
|
||||
VTKM_CONT
|
||||
void SetMergeDuplicatePoints(bool on);
|
||||
|
||||
VTKM_CONT
|
||||
bool GetMergeDuplicatePoints() const;
|
||||
|
||||
/// Set/Get whether normals should be generated. Off by default. If enabled,
|
||||
/// the default behaviour is to generate high quality normals for structured
|
||||
/// datasets, using gradients, and generate fast normals for unstructured
|
||||
/// datasets based on the result triangle mesh.
|
||||
///
|
||||
VTKM_CONT
|
||||
void SetGenerateNormals(bool on) { this->GenerateNormals = on; }
|
||||
VTKM_CONT
|
||||
bool GetGenerateNormals() const { return this->GenerateNormals; }
|
||||
|
||||
/// Set/Get whether to append the ids of the intersected edges to the vertices of the isosurface triangles. Off by default.
|
||||
VTKM_CONT
|
||||
void SetAddInterpolationEdgeIds(bool on) { this->AddInterpolationEdgeIds = on; }
|
||||
VTKM_CONT
|
||||
bool GetAddInterpolationEdgeIds() const { return this->AddInterpolationEdgeIds; }
|
||||
|
||||
/// Set/Get whether the fast path should be used for normals computation for
|
||||
/// structured datasets. Off by default.
|
||||
VTKM_CONT
|
||||
void SetComputeFastNormalsForStructured(bool on) { this->ComputeFastNormalsForStructured = on; }
|
||||
VTKM_CONT
|
||||
bool GetComputeFastNormalsForStructured() const { return this->ComputeFastNormalsForStructured; }
|
||||
VTKM_DEPRECATED(2.1, "Use SetComputeFastNormals.")
|
||||
VTKM_CONT void SetComputeFastNormalsForStructured(bool on) { this->SetComputeFastNormals(on); }
|
||||
VTKM_DEPRECATED(2.1, "Use GetComputeFastNormals.")
|
||||
VTKM_CONT bool GetComputeFastNormalsForStructured() const
|
||||
{
|
||||
return this->GetComputeFastNormals();
|
||||
}
|
||||
|
||||
/// Set/Get whether the fast path should be used for normals computation for
|
||||
/// unstructured datasets. On by default.
|
||||
VTKM_CONT
|
||||
void SetComputeFastNormalsForUnstructured(bool on)
|
||||
VTKM_DEPRECATED(2.1, "Use SetComputeFastNormals.")
|
||||
VTKM_CONT void SetComputeFastNormalsForUnstructured(bool on) { this->SetComputeFastNormals(on); }
|
||||
VTKM_DEPRECATED(2.1, "Use GetComputeFastNormals.")
|
||||
VTKM_CONT bool GetComputeFastNormalsForUnstructured() const
|
||||
{
|
||||
this->ComputeFastNormalsForUnstructured = on;
|
||||
return this->GetComputeFastNormals();
|
||||
}
|
||||
VTKM_CONT
|
||||
bool GetComputeFastNormalsForUnstructured() const
|
||||
{
|
||||
return this->ComputeFastNormalsForUnstructured;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void SetNormalArrayName(const std::string& name) { this->NormalArrayName = name; }
|
||||
|
||||
VTKM_CONT
|
||||
const std::string& GetNormalArrayName() const { return this->NormalArrayName; }
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
|
||||
std::vector<vtkm::Float64> IsoValues;
|
||||
bool GenerateNormals = false;
|
||||
bool AddInterpolationEdgeIds = false;
|
||||
bool ComputeFastNormalsForStructured = false;
|
||||
bool ComputeFastNormalsForUnstructured = true;
|
||||
bool MergeDuplicatedPoints = true;
|
||||
std::string NormalArrayName = "normals";
|
||||
std::string InterpolationEdgeIdsArrayName = "edgeIds";
|
||||
|
||||
protected:
|
||||
// Needed by the subclass Slice
|
||||
|
98
vtkm/filter/contour/ContourFlyingEdges.cxx
Normal file
98
vtkm/filter/contour/ContourFlyingEdges.cxx
Normal file
@ -0,0 +1,98 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/CellSetSingleType.h>
|
||||
#include <vtkm/cont/CellSetStructured.h>
|
||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||
#include <vtkm/cont/UnknownCellSet.h>
|
||||
|
||||
#include <vtkm/filter/contour/ContourFlyingEdges.h>
|
||||
#include <vtkm/filter/contour/worklet/ContourFlyingEdges.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
|
||||
using SupportedTypes = vtkm::List<vtkm::UInt8, vtkm::Int8, vtkm::Float32, vtkm::Float64>;
|
||||
|
||||
namespace contour
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
vtkm::cont::DataSet ContourFlyingEdges::DoExecute(const vtkm::cont::DataSet& inDataSet)
|
||||
{
|
||||
vtkm::worklet::ContourFlyingEdges worklet;
|
||||
worklet.SetMergeDuplicatePoints(this->GetMergeDuplicatePoints());
|
||||
|
||||
if (!this->GetFieldFromDataSet(inDataSet).IsPointField())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution("Point field expected.");
|
||||
}
|
||||
|
||||
if (this->IsoValues.empty())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution("No iso-values provided.");
|
||||
}
|
||||
|
||||
vtkm::cont::UnknownCellSet inCellSet = inDataSet.GetCellSet();
|
||||
const vtkm::cont::CoordinateSystem& inCoords =
|
||||
inDataSet.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex());
|
||||
|
||||
if (!inCellSet.template IsType<vtkm::cont::CellSetStructured<3>>())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution("This filter is only available for 3-Dimensional "
|
||||
"Structured Cell Sets");
|
||||
}
|
||||
|
||||
// Get the CellSet's known dynamic type
|
||||
const vtkm::cont::CellSetStructured<3>& inputCells =
|
||||
inDataSet.GetCellSet().AsCellSet<vtkm::cont::CellSetStructured<3>>();
|
||||
|
||||
using Vec3HandleType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
|
||||
Vec3HandleType vertices;
|
||||
Vec3HandleType normals;
|
||||
|
||||
vtkm::cont::CellSetSingleType<> outputCells;
|
||||
|
||||
auto resolveFieldType = [&](const auto& concrete) {
|
||||
// use std::decay to remove const ref from the decltype of concrete.
|
||||
using T = typename std::decay_t<decltype(concrete)>::ValueType;
|
||||
std::vector<T> ivalues(this->IsoValues.size());
|
||||
for (std::size_t i = 0; i < ivalues.size(); ++i)
|
||||
{
|
||||
ivalues[i] = static_cast<T>(this->IsoValues[i]);
|
||||
}
|
||||
|
||||
if (this->GenerateNormals && !this->GetComputeFastNormals())
|
||||
{
|
||||
outputCells = worklet.Run(ivalues, inputCells, inCoords, concrete, vertices, normals);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputCells = worklet.Run(ivalues, inputCells, inCoords, concrete, vertices);
|
||||
}
|
||||
};
|
||||
|
||||
this->GetFieldFromDataSet(inDataSet)
|
||||
.GetData()
|
||||
.CastAndCallForTypesWithFloatFallback<SupportedTypes, VTKM_DEFAULT_STORAGE_LIST>(
|
||||
resolveFieldType);
|
||||
|
||||
auto mapper = [&](auto& result, const auto& f) { this->DoMapField(result, f, worklet); };
|
||||
vtkm::cont::DataSet output = this->CreateResultCoordinateSystem(
|
||||
inDataSet, outputCells, inCoords.GetName(), vertices, mapper);
|
||||
|
||||
this->ExecuteGenerateNormals(output, normals);
|
||||
this->ExecuteAddInterpolationEdgeIds(output, worklet);
|
||||
|
||||
return output;
|
||||
}
|
||||
} // namespace contour
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
41
vtkm/filter/contour/ContourFlyingEdges.h
Normal file
41
vtkm/filter/contour/ContourFlyingEdges.h
Normal file
@ -0,0 +1,41 @@
|
||||
//============================================================================
|
||||
// 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_contour_ContourFlyingEdges_h
|
||||
#define vtk_m_filter_contour_ContourFlyingEdges_h
|
||||
|
||||
#include <vtkm/filter/contour/AbstractContour.h>
|
||||
#include <vtkm/filter/contour/vtkm_filter_contour_export.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
namespace contour
|
||||
{
|
||||
/// \brief generate isosurface(s) from a 3-dimensional structured mesh
|
||||
|
||||
/// Takes as input a 3D structured mesh and generates on
|
||||
/// output one or more isosurfaces using the Flying Edges algorithm.
|
||||
/// Multiple contour values must be specified to generate the isosurfaces.
|
||||
///
|
||||
/// This implementation only accepts \c CellSetStructured<3> inputs using
|
||||
/// \c ArrayHandleUniformPointCoordinates for point coordinates,
|
||||
/// and is only used as part of the more general \c Contour filter
|
||||
class VTKM_FILTER_CONTOUR_EXPORT ContourFlyingEdges : public vtkm::filter::contour::AbstractContour
|
||||
{
|
||||
protected:
|
||||
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& result) override;
|
||||
};
|
||||
} // namespace contour
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
||||
|
||||
#endif // vtk_m_filter_contour_ContourFlyingEdges_h
|
85
vtkm/filter/contour/ContourMarchingCells.cxx
Normal file
85
vtkm/filter/contour/ContourMarchingCells.cxx
Normal file
@ -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.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/CellSetSingleType.h>
|
||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||
#include <vtkm/cont/UnknownCellSet.h>
|
||||
|
||||
#include <vtkm/filter/contour/ContourMarchingCells.h>
|
||||
#include <vtkm/filter/contour/worklet/ContourMarchingCells.h>
|
||||
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
namespace contour
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
vtkm::cont::DataSet ContourMarchingCells::DoExecute(const vtkm::cont::DataSet& inDataSet)
|
||||
{
|
||||
vtkm::worklet::ContourMarchingCells worklet;
|
||||
worklet.SetMergeDuplicatePoints(this->GetMergeDuplicatePoints());
|
||||
|
||||
if (!this->GetFieldFromDataSet(inDataSet).IsPointField())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution("Point field expected.");
|
||||
}
|
||||
|
||||
if (this->IsoValues.empty())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution("No iso-values provided.");
|
||||
}
|
||||
|
||||
//get the inputCells and coordinates of the dataset
|
||||
const vtkm::cont::UnknownCellSet& inputCells = inDataSet.GetCellSet();
|
||||
const vtkm::cont::CoordinateSystem& inputCoords =
|
||||
inDataSet.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex());
|
||||
|
||||
using Vec3HandleType = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
|
||||
Vec3HandleType vertices;
|
||||
Vec3HandleType normals;
|
||||
|
||||
vtkm::cont::CellSetSingleType<> outputCells;
|
||||
|
||||
auto resolveFieldType = [&](const auto& concrete) {
|
||||
// use std::decay to remove const ref from the decltype of concrete.
|
||||
using T = typename std::decay_t<decltype(concrete)>::ValueType;
|
||||
std::vector<T> ivalues(this->IsoValues.size());
|
||||
for (std::size_t i = 0; i < ivalues.size(); ++i)
|
||||
{
|
||||
ivalues[i] = static_cast<T>(this->IsoValues[i]);
|
||||
}
|
||||
|
||||
if (this->GenerateNormals && !this->GetComputeFastNormals())
|
||||
{
|
||||
outputCells =
|
||||
worklet.Run(ivalues, inputCells, inputCoords.GetData(), concrete, vertices, normals);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputCells = worklet.Run(ivalues, inputCells, inputCoords.GetData(), concrete, vertices);
|
||||
}
|
||||
};
|
||||
|
||||
this->CastAndCallScalarField(this->GetFieldFromDataSet(inDataSet), resolveFieldType);
|
||||
|
||||
auto mapper = [&](auto& result, const auto& f) { this->DoMapField(result, f, worklet); };
|
||||
vtkm::cont::DataSet output = this->CreateResultCoordinateSystem(
|
||||
inDataSet, outputCells, inputCoords.GetName(), vertices, mapper);
|
||||
|
||||
this->ExecuteGenerateNormals(output, normals);
|
||||
this->ExecuteAddInterpolationEdgeIds(output, worklet);
|
||||
|
||||
|
||||
return output;
|
||||
}
|
||||
} // namespace contour
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
43
vtkm/filter/contour/ContourMarchingCells.h
Normal file
43
vtkm/filter/contour/ContourMarchingCells.h
Normal file
@ -0,0 +1,43 @@
|
||||
//============================================================================
|
||||
// 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_contour_ContourMarchingCells_h
|
||||
#define vtk_m_filter_contour_ContourMarchingCells_h
|
||||
|
||||
#include <vtkm/filter/contour/AbstractContour.h>
|
||||
#include <vtkm/filter/contour/vtkm_filter_contour_export.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
namespace contour
|
||||
{
|
||||
/// \brief generate isosurface(s) from a Volume using the Marching Cells algorithm
|
||||
///
|
||||
/// Takes as input a volume (e.g., 3D structured point set) and generates on
|
||||
/// output one or more isosurfaces.
|
||||
/// Multiple contour values must be specified to generate the isosurfaces.
|
||||
///
|
||||
/// This implementation is not optimized for all use cases, it is used by
|
||||
/// the more general \c Contour filter which selects the best implementation
|
||||
/// for all types of \c DataSet . .
|
||||
class VTKM_FILTER_CONTOUR_EXPORT ContourMarchingCells
|
||||
: public vtkm::filter::contour::AbstractContour
|
||||
{
|
||||
protected:
|
||||
VTKM_CONT
|
||||
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& result) override;
|
||||
};
|
||||
} // namespace contour
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
||||
|
||||
#endif // vtk_m_filter_contour_ContourMarchingCells_h
|
@ -11,10 +11,13 @@
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
#include <vtkm/filter/contour/Contour.h>
|
||||
#include <vtkm/filter/contour/ContourFlyingEdges.h>
|
||||
#include <vtkm/filter/contour/ContourMarchingCells.h>
|
||||
#include <vtkm/filter/field_transform/GenerateIds.h>
|
||||
|
||||
#include <vtkm/io/VTKDataSetReader.h>
|
||||
@ -26,7 +29,8 @@ namespace
|
||||
class TestContourFilter
|
||||
{
|
||||
public:
|
||||
void TestContourUniformGrid() const
|
||||
template <typename ContourFilterType>
|
||||
void TestContourUniformGrid(vtkm::IdComponent numPointsNoMergeDuplicate) const
|
||||
{
|
||||
std::cout << "Testing Contour filter on a uniform grid" << std::endl;
|
||||
|
||||
@ -38,14 +42,14 @@ public:
|
||||
genIds.SetCellFieldName("cellvar");
|
||||
vtkm::cont::DataSet dataSet = genIds.Execute(tangle.Execute());
|
||||
|
||||
vtkm::filter::contour::Contour mc;
|
||||
ContourFilterType filter;
|
||||
|
||||
mc.SetGenerateNormals(true);
|
||||
mc.SetIsoValue(0, 0.5);
|
||||
mc.SetActiveField("tangle");
|
||||
mc.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::None);
|
||||
filter.SetGenerateNormals(true);
|
||||
filter.SetIsoValue(0, 0.5);
|
||||
filter.SetActiveField("tangle");
|
||||
filter.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::None);
|
||||
|
||||
auto result = mc.Execute(dataSet);
|
||||
auto result = filter.Execute(dataSet);
|
||||
{
|
||||
VTKM_TEST_ASSERT(result.GetNumberOfCoordinateSystems() == 1,
|
||||
"Wrong number of coordinate systems in the output dataset");
|
||||
@ -55,8 +59,8 @@ public:
|
||||
}
|
||||
|
||||
// let's execute with mapping fields.
|
||||
mc.SetFieldsToPass({ "tangle", "cellvar" });
|
||||
result = mc.Execute(dataSet);
|
||||
filter.SetFieldsToPass({ "tangle", "cellvar" });
|
||||
result = filter.Execute(dataSet);
|
||||
{
|
||||
const bool isMapped = result.HasField("tangle");
|
||||
VTKM_TEST_ASSERT(isMapped, "mapping should pass");
|
||||
@ -99,16 +103,13 @@ public:
|
||||
VTKM_TEST_ASSERT(cells.GetNumberOfCells() == 160, "");
|
||||
}
|
||||
|
||||
//Now try with vertex merging disabled. Since this
|
||||
//we use FlyingEdges we now which does point merging for free
|
||||
//so we should see the number of points not change
|
||||
mc.SetMergeDuplicatePoints(false);
|
||||
mc.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::All);
|
||||
result = mc.Execute(dataSet);
|
||||
//Now try with vertex merging disabled.
|
||||
filter.SetMergeDuplicatePoints(false);
|
||||
filter.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::All);
|
||||
result = filter.Execute(dataSet);
|
||||
{
|
||||
vtkm::cont::CoordinateSystem coords = result.GetCoordinateSystem();
|
||||
|
||||
VTKM_TEST_ASSERT(coords.GetNumberOfPoints() == 72,
|
||||
VTKM_TEST_ASSERT(coords.GetNumberOfPoints() == numPointsNoMergeDuplicate,
|
||||
"Shouldn't have less coordinates than the unmerged version");
|
||||
|
||||
//verify that the number of cells is correct (160)
|
||||
@ -120,20 +121,24 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ContourFilterType>
|
||||
void Test3DUniformDataSet0() const
|
||||
{
|
||||
vtkm::cont::testing::MakeTestDataSet maker;
|
||||
vtkm::cont::DataSet inputData = maker.Make3DUniformDataSet0();
|
||||
std::string fieldName = "pointvar";
|
||||
|
||||
// Defend the test against changes to Make3DUniformDataSet0():
|
||||
VTKM_TEST_ASSERT(inputData.HasField(fieldName));
|
||||
vtkm::cont::Field pointField = inputData.GetField(fieldName);
|
||||
|
||||
vtkm::Range range;
|
||||
pointField.GetRange(&range);
|
||||
vtkm::FloatDefault isovalue = 100.0;
|
||||
// Range = [10.1, 180.5]
|
||||
VTKM_TEST_ASSERT(range.Contains(isovalue));
|
||||
vtkm::filter::contour::Contour filter;
|
||||
|
||||
ContourFilterType filter;
|
||||
filter.SetGenerateNormals(false);
|
||||
filter.SetMergeDuplicatePoints(true);
|
||||
filter.SetIsoValue(isovalue);
|
||||
@ -143,6 +148,7 @@ public:
|
||||
VTKM_TEST_ASSERT(outputData.GetNumberOfPoints() == 9);
|
||||
}
|
||||
|
||||
template <typename ContourFilterType>
|
||||
void TestContourWedges() const
|
||||
{
|
||||
std::cout << "Testing Contour filter on wedge cells" << std::endl;
|
||||
@ -158,7 +164,7 @@ public:
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> fieldArray;
|
||||
dataSet.GetPointField("gyroid").GetData().AsArrayHandle(fieldArray);
|
||||
|
||||
vtkm::filter::contour::Contour isosurfaceFilter;
|
||||
ContourFilterType isosurfaceFilter;
|
||||
isosurfaceFilter.SetActiveField("gyroid");
|
||||
isosurfaceFilter.SetMergeDuplicatePoints(false);
|
||||
isosurfaceFilter.SetIsoValue(0.0);
|
||||
@ -167,11 +173,98 @@ public:
|
||||
VTKM_TEST_ASSERT(result.GetNumberOfCells() == 52);
|
||||
}
|
||||
|
||||
void TestUnsupportedFlyingEdges() const
|
||||
{
|
||||
vtkm::cont::testing::MakeTestDataSet maker;
|
||||
vtkm::cont::DataSet explicitDataSet = maker.Make3DExplicitDataSet0();
|
||||
|
||||
vtkm::filter::contour::ContourFlyingEdges filter;
|
||||
filter.SetIsoValue(2.0);
|
||||
filter.SetActiveField("pointvar");
|
||||
|
||||
try
|
||||
{
|
||||
filter.Execute(explicitDataSet);
|
||||
VTKM_TEST_FAIL("Flying Edges filter should not run on explicit datasets");
|
||||
}
|
||||
catch (vtkm::cont::ErrorFilterExecution&)
|
||||
{
|
||||
std::cout << "Execution successfully aborted" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ContourFilterType>
|
||||
void TestNonUniformStructured() const
|
||||
{
|
||||
auto pathname =
|
||||
vtkm::cont::testing::Testing::DataPath("rectilinear/simple_rectilinear1_ascii.vtk");
|
||||
vtkm::io::VTKDataSetReader reader(pathname);
|
||||
vtkm::cont::DataSet rectilinearDataset = reader.ReadDataSet();
|
||||
|
||||
// Single-cell contour
|
||||
ContourFilterType filter;
|
||||
filter.SetActiveField("var");
|
||||
filter.SetIsoValue(2.0);
|
||||
vtkm::cont::DataSet outputSingleCell = filter.Execute(rectilinearDataset);
|
||||
auto coordinates = outputSingleCell.GetCoordinateSystem()
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Vec3f>>();
|
||||
|
||||
VTKM_TEST_ASSERT(outputSingleCell.GetNumberOfPoints() == 3,
|
||||
"Wrong number of points in rectilinear contour");
|
||||
VTKM_TEST_ASSERT(outputSingleCell.GetNumberOfCells() == 1,
|
||||
"Wrong number of cells in rectilinear contour");
|
||||
VTKM_TEST_ASSERT(outputSingleCell.GetCellSet().GetCellShape(0) == vtkm::CELL_SHAPE_TRIANGLE,
|
||||
"Wrong contour cell shape");
|
||||
|
||||
auto expectedCoordinates =
|
||||
vtkm::cont::make_ArrayHandle<vtkm::Vec3f>({ vtkm::Vec3f{ 10.0f, -10.0f, 9.66341f },
|
||||
vtkm::Vec3f{ 9.30578f, -10.0f, 10.0f },
|
||||
vtkm::Vec3f{ 10.0f, -9.78842f, 10.0f } });
|
||||
VTKM_TEST_ASSERT(test_equal_ArrayHandles(coordinates, expectedCoordinates),
|
||||
"Wrong contour coordinates");
|
||||
|
||||
// Generating normals triggers a different worklet for Flying Edges pass 4,
|
||||
// But it should not change anything on the contour itself.
|
||||
filter.SetGenerateNormals(true);
|
||||
vtkm::cont::DataSet outputNormals = filter.Execute(rectilinearDataset);
|
||||
coordinates = outputNormals.GetCoordinateSystem()
|
||||
.GetData()
|
||||
.AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Vec3f>>();
|
||||
VTKM_TEST_ASSERT(test_equal_ArrayHandles(coordinates, expectedCoordinates),
|
||||
"Wrong contour coordinates");
|
||||
|
||||
// Full contour
|
||||
filter.SetIsoValue(3.0);
|
||||
filter.SetGenerateNormals(false);
|
||||
vtkm::cont::DataSet output = filter.Execute(rectilinearDataset);
|
||||
|
||||
VTKM_TEST_ASSERT(output.GetNumberOfPoints() == 93,
|
||||
"Wrong number of points in rectilinear contour");
|
||||
VTKM_TEST_ASSERT(output.GetNumberOfCells() == 144,
|
||||
"Wrong number of cells in rectilinear contour");
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
this->Test3DUniformDataSet0();
|
||||
this->TestContourUniformGrid();
|
||||
this->TestContourWedges();
|
||||
this->TestContourUniformGrid<vtkm::filter::contour::Contour>(72);
|
||||
this->TestContourUniformGrid<vtkm::filter::contour::ContourFlyingEdges>(72);
|
||||
// Unlike flying edges, marching cells does not have point merging for free,
|
||||
// So the number of points should increase when disabling duplicate point merging.
|
||||
this->TestContourUniformGrid<vtkm::filter::contour::ContourMarchingCells>(480);
|
||||
|
||||
this->Test3DUniformDataSet0<vtkm::filter::contour::Contour>();
|
||||
this->Test3DUniformDataSet0<vtkm::filter::contour::ContourMarchingCells>();
|
||||
this->Test3DUniformDataSet0<vtkm::filter::contour::ContourFlyingEdges>();
|
||||
|
||||
this->TestContourWedges<vtkm::filter::contour::Contour>();
|
||||
this->TestContourWedges<vtkm::filter::contour::ContourMarchingCells>();
|
||||
|
||||
this->TestNonUniformStructured<vtkm::filter::contour::Contour>();
|
||||
this->TestNonUniformStructured<vtkm::filter::contour::ContourFlyingEdges>();
|
||||
this->TestNonUniformStructured<vtkm::filter::contour::ContourMarchingCells>();
|
||||
|
||||
this->TestUnsupportedFlyingEdges();
|
||||
}
|
||||
|
||||
}; // class TestContourFilter
|
||||
|
@ -105,6 +105,14 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
||||
vtkm::filter::contour::Contour mc;
|
||||
mc.SetIsoValue(0, 200);
|
||||
mc.SetGenerateNormals(true);
|
||||
if (structured)
|
||||
{
|
||||
mc.SetComputeFastNormals(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
mc.SetComputeFastNormals(true);
|
||||
}
|
||||
|
||||
// Test default normals generation: high quality for structured, fast for unstructured.
|
||||
auto expected = structured ? hq_sg : fast;
|
||||
@ -136,7 +144,7 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
||||
// Test the other normals generation method
|
||||
if (structured)
|
||||
{
|
||||
mc.SetComputeFastNormalsForStructured(true);
|
||||
mc.SetComputeFastNormals(true);
|
||||
expected = fast;
|
||||
if (using_fe_y_alg_ordering)
|
||||
{
|
||||
@ -145,7 +153,7 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
||||
}
|
||||
else
|
||||
{
|
||||
mc.SetComputeFastNormalsForUnstructured(false);
|
||||
mc.SetComputeFastNormals(false);
|
||||
expected = hq_ug;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,8 @@
|
||||
|
||||
set(headers
|
||||
Clip.h
|
||||
Contour.h
|
||||
ContourFlyingEdges.h
|
||||
ContourMarchingCells.h
|
||||
MIR.h
|
||||
)
|
||||
|
||||
|
116
vtkm/filter/contour/worklet/ContourFlyingEdges.h
Normal file
116
vtkm/filter/contour/worklet/ContourFlyingEdges.h
Normal file
@ -0,0 +1,116 @@
|
||||
//============================================================================
|
||||
// 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_worklet_ContourFlyingEdges_h
|
||||
#define vtk_m_worklet_ContourFlyingEdges_h
|
||||
|
||||
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#include <vtkm/filter/contour/worklet/contour/CommonState.h>
|
||||
#include <vtkm/filter/contour/worklet/contour/FieldPropagation.h>
|
||||
#include <vtkm/filter/contour/worklet/contour/FlyingEdges.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
|
||||
/// \brief Compute the isosurface of a given \c CellSetStructured<3> input with
|
||||
/// \c ArrayHandleUniformPointCoordinates for point coordinates using the Flying Edges algorithm.
|
||||
class ContourFlyingEdges
|
||||
{
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
ContourFlyingEdges(bool mergeDuplicates = true)
|
||||
: SharedState(mergeDuplicates)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkm::cont::ArrayHandle<vtkm::Id2> GetInterpolationEdgeIds() const
|
||||
{
|
||||
return this->SharedState.InterpolationEdgeIds;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void SetMergeDuplicatePoints(bool merge) { this->SharedState.MergeDuplicatePoints = merge; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool GetMergeDuplicatePoints() const { return this->SharedState.MergeDuplicatePoints; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> GetCellIdMap() const { return this->SharedState.CellIdMap; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename InArrayType, typename OutArrayType>
|
||||
void ProcessPointField(const InArrayType& input, const OutArrayType& output) const
|
||||
{
|
||||
|
||||
using vtkm::worklet::contour::MapPointField;
|
||||
vtkm::worklet::DispatcherMapField<MapPointField> applyFieldDispatcher;
|
||||
|
||||
applyFieldDispatcher.Invoke(this->SharedState.InterpolationEdgeIds,
|
||||
this->SharedState.InterpolationWeights,
|
||||
input,
|
||||
output);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void ReleaseCellMapArrays() { this->SharedState.CellIdMap.ReleaseResources(); }
|
||||
|
||||
// Filter called without normals generation
|
||||
template <typename ValueType,
|
||||
typename CoordsType,
|
||||
typename StorageTagField,
|
||||
typename CoordinateType,
|
||||
typename StorageTagVertices>
|
||||
vtkm::cont::CellSetSingleType<> Run(
|
||||
const std::vector<ValueType>& isovalues,
|
||||
const vtkm::cont::CellSetStructured<3>& cells,
|
||||
const CoordsType& coordinateSystem,
|
||||
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& input,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<CoordinateType, 3>, StorageTagVertices>& vertices)
|
||||
{
|
||||
this->SharedState.GenerateNormals = false;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<CoordinateType, 3>> normals;
|
||||
|
||||
vtkm::cont::CellSetSingleType<> outputCells;
|
||||
return flying_edges::execute(
|
||||
cells, coordinateSystem, isovalues, input, vertices, normals, this->SharedState);
|
||||
}
|
||||
|
||||
// Filter called with normals generation
|
||||
template <typename ValueType,
|
||||
typename CoordsType,
|
||||
typename StorageTagField,
|
||||
typename CoordinateType,
|
||||
typename StorageTagVertices,
|
||||
typename StorageTagNormals>
|
||||
vtkm::cont::CellSetSingleType<> Run(
|
||||
const std::vector<ValueType>& isovalues,
|
||||
const vtkm::cont::CellSetStructured<3>& cells,
|
||||
const CoordsType& coordinateSystem,
|
||||
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& input,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<CoordinateType, 3>, StorageTagVertices>& vertices,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<CoordinateType, 3>, StorageTagNormals>& normals)
|
||||
{
|
||||
this->SharedState.GenerateNormals = true;
|
||||
vtkm::cont::CellSetSingleType<> outputCells;
|
||||
return flying_edges::execute(
|
||||
cells, coordinateSystem, isovalues, input, vertices, normals, this->SharedState);
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::worklet::contour::CommonState SharedState;
|
||||
};
|
||||
}
|
||||
} // namespace vtkm::worklet
|
||||
|
||||
#endif // vtk_m_worklet_ContourFlyingEdges_h
|
@ -8,16 +8,11 @@
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_worklet_Contour_h
|
||||
#define vtk_m_worklet_Contour_h
|
||||
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#ifndef vtk_m_worklet_ContourMarchingCells_h
|
||||
#define vtk_m_worklet_ContourMarchingCells_h
|
||||
|
||||
#include <vtkm/filter/contour/worklet/contour/CommonState.h>
|
||||
#include <vtkm/filter/contour/worklet/contour/FieldPropagation.h>
|
||||
#include <vtkm/filter/contour/worklet/contour/FlyingEdges.h>
|
||||
#include <vtkm/filter/contour/worklet/contour/MarchingCells.h>
|
||||
|
||||
|
||||
@ -25,8 +20,6 @@ namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
|
||||
|
||||
namespace contour
|
||||
{
|
||||
struct DeduceCoordType
|
||||
@ -39,16 +32,6 @@ struct DeduceCoordType
|
||||
{
|
||||
result = marching_cells::execute(cells, coords, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec3f, vtkm::cont::StorageTagUniformPoints>& coords,
|
||||
const vtkm::cont::CellSetStructured<3>& cells,
|
||||
vtkm::cont::CellSetSingleType<>& result,
|
||||
Args&&... args) const
|
||||
{
|
||||
result = flying_edges::execute(cells, coords, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
struct DeduceCellType
|
||||
@ -62,13 +45,12 @@ struct DeduceCellType
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief Compute the isosurface of a given 3D data set, supports all
|
||||
/// linear cell types
|
||||
class Contour
|
||||
/// \brief Compute the isosurface of a given 3D data set, supports all linear cell types
|
||||
class ContourMarchingCells
|
||||
{
|
||||
public:
|
||||
//----------------------------------------------------------------------------
|
||||
Contour(bool mergeDuplicates = true)
|
||||
ContourMarchingCells(bool mergeDuplicates = true)
|
||||
: SharedState(mergeDuplicates)
|
||||
{
|
||||
}
|
||||
@ -89,6 +71,23 @@ public:
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> GetCellIdMap() const { return this->SharedState.CellIdMap; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename InArrayType, typename OutArrayType>
|
||||
void ProcessPointField(const InArrayType& input, const OutArrayType& output) const
|
||||
{
|
||||
|
||||
using vtkm::worklet::contour::MapPointField;
|
||||
vtkm::worklet::DispatcherMapField<MapPointField> applyFieldDispatcher;
|
||||
|
||||
applyFieldDispatcher.Invoke(this->SharedState.InterpolationEdgeIds,
|
||||
this->SharedState.InterpolationWeights,
|
||||
input,
|
||||
output);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void ReleaseCellMapArrays() { this->SharedState.CellIdMap.ReleaseResources(); }
|
||||
|
||||
// Filter called without normals generation
|
||||
template <typename ValueType,
|
||||
typename CellSetType,
|
||||
typename CoordinateSystem,
|
||||
@ -118,7 +117,7 @@ public:
|
||||
return outputCells;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Filter called with normals generation
|
||||
template <typename ValueType,
|
||||
typename CellSetType,
|
||||
typename CoordinateSystem,
|
||||
@ -149,22 +148,6 @@ public:
|
||||
return outputCells;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename InArrayType, typename OutArrayType>
|
||||
void ProcessPointField(const InArrayType& input, const OutArrayType& output) const
|
||||
{
|
||||
|
||||
using vtkm::worklet::contour::MapPointField;
|
||||
vtkm::worklet::DispatcherMapField<MapPointField> applyFieldDispatcher;
|
||||
|
||||
applyFieldDispatcher.Invoke(this->SharedState.InterpolationEdgeIds,
|
||||
this->SharedState.InterpolationWeights,
|
||||
input,
|
||||
output);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void ReleaseCellMapArrays() { this->SharedState.CellIdMap.ReleaseResources(); }
|
||||
|
||||
private:
|
||||
vtkm::worklet::contour::CommonState SharedState;
|
||||
@ -172,4 +155,4 @@ private:
|
||||
}
|
||||
} // namespace vtkm::worklet
|
||||
|
||||
#endif // vtk_m_worklet_Contour_h
|
||||
#endif // vtk_m_worklet_ContourMarchingCells_h
|
@ -41,6 +41,7 @@ vtkm::Id extend_by(vtkm::cont::ArrayHandle<T, S>& handle, vtkm::Id size)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename ValueType,
|
||||
typename CoordsType,
|
||||
typename StorageTagField,
|
||||
typename StorageTagVertices,
|
||||
typename StorageTagNormals,
|
||||
@ -48,7 +49,7 @@ template <typename ValueType,
|
||||
typename NormalType>
|
||||
vtkm::cont::CellSetSingleType<> execute(
|
||||
const vtkm::cont::CellSetStructured<3>& cells,
|
||||
const vtkm::cont::ArrayHandleUniformPointCoordinates& coordinateSystem,
|
||||
const CoordsType coordinateSystem,
|
||||
const std::vector<ValueType>& isovalues,
|
||||
const vtkm::cont::ArrayHandle<ValueType, StorageTagField>& inputField,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<CoordinateType, 3>, StorageTagVertices>& points,
|
||||
@ -56,18 +57,10 @@ vtkm::cont::CellSetSingleType<> execute(
|
||||
vtkm::worklet::contour::CommonState& sharedState)
|
||||
{
|
||||
vtkm::cont::Invoker invoke;
|
||||
|
||||
vtkm::Vec3f origin, spacing;
|
||||
{ //extract out the origin and spacing as these are needed for Pass4 to properly
|
||||
//interpolate the new points
|
||||
auto portal = coordinateSystem.ReadPortal();
|
||||
origin = portal.GetOrigin();
|
||||
spacing = portal.GetSpacing();
|
||||
}
|
||||
auto pdims = cells.GetPointDimensions();
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> edgeCases;
|
||||
edgeCases.Allocate(coordinateSystem.GetNumberOfValues());
|
||||
edgeCases.Allocate(coordinateSystem.GetData().GetNumberOfValues());
|
||||
|
||||
vtkm::cont::CellSetStructured<2> metaDataMesh2D;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> metaDataLinearSums; //per point of metaDataMesh
|
||||
@ -158,8 +151,7 @@ vtkm::cont::CellSetSingleType<> execute(
|
||||
{
|
||||
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "FlyingEdges Pass4");
|
||||
|
||||
launchComputePass4 pass4(
|
||||
pdims, origin, spacing, multiContourCellOffset, multiContourPointOffset);
|
||||
auto pass4 = launchComputePass4(pdims, multiContourCellOffset, multiContourPointOffset);
|
||||
|
||||
detail::extend_by(points, newPointSize);
|
||||
if (sharedState.GenerateNormals)
|
||||
@ -171,6 +163,7 @@ vtkm::cont::CellSetSingleType<> execute(
|
||||
pass4,
|
||||
newPointSize,
|
||||
isoval,
|
||||
coordinateSystem,
|
||||
inputField,
|
||||
edgeCases,
|
||||
metaDataMesh2D,
|
||||
|
@ -28,20 +28,14 @@ namespace flying_edges
|
||||
struct launchComputePass4
|
||||
{
|
||||
vtkm::Id3 PointDims;
|
||||
vtkm::Vec3f Origin;
|
||||
vtkm::Vec3f Spacing;
|
||||
|
||||
vtkm::Id CellWriteOffset;
|
||||
vtkm::Id PointWriteOffset;
|
||||
|
||||
launchComputePass4(const vtkm::Id3& pdims,
|
||||
const vtkm::Vec3f& origin,
|
||||
const vtkm::Vec3f& spacing,
|
||||
vtkm::Id multiContourCellOffset,
|
||||
vtkm::Id multiContourPointOffset)
|
||||
: PointDims(pdims)
|
||||
, Origin(origin)
|
||||
, Spacing(spacing)
|
||||
, CellWriteOffset(multiContourCellOffset)
|
||||
, PointWriteOffset(multiContourPointOffset)
|
||||
{
|
||||
@ -49,6 +43,7 @@ struct launchComputePass4
|
||||
|
||||
template <typename DeviceAdapterTag,
|
||||
typename T,
|
||||
typename CoordsType,
|
||||
typename StorageTagField,
|
||||
typename MeshSums,
|
||||
typename PointType,
|
||||
@ -56,6 +51,7 @@ struct launchComputePass4
|
||||
VTKM_CONT bool LaunchXAxis(DeviceAdapterTag device,
|
||||
vtkm::Id vtkmNotUsed(newPointSize),
|
||||
T isoval,
|
||||
CoordsType coordinateSystem,
|
||||
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> edgeCases,
|
||||
vtkm::cont::CellSetStructured<2>& metaDataMesh2D,
|
||||
@ -71,12 +67,8 @@ struct launchComputePass4
|
||||
vtkm::cont::Invoker invoke(device);
|
||||
if (sharedState.GenerateNormals)
|
||||
{
|
||||
ComputePass4XWithNormals<T> worklet4(isoval,
|
||||
this->PointDims,
|
||||
this->Origin,
|
||||
this->Spacing,
|
||||
this->CellWriteOffset,
|
||||
this->PointWriteOffset);
|
||||
ComputePass4XWithNormals<T> worklet4(
|
||||
isoval, this->PointDims, this->CellWriteOffset, this->PointWriteOffset);
|
||||
invoke(worklet4,
|
||||
metaDataMesh2D,
|
||||
metaDataSums,
|
||||
@ -84,6 +76,7 @@ struct launchComputePass4
|
||||
metaDataMax,
|
||||
metaDataNumTris,
|
||||
edgeCases,
|
||||
coordinateSystem,
|
||||
inputField,
|
||||
triangle_topology,
|
||||
sharedState.InterpolationEdgeIds,
|
||||
@ -94,12 +87,8 @@ struct launchComputePass4
|
||||
}
|
||||
else
|
||||
{
|
||||
ComputePass4X<T> worklet4(isoval,
|
||||
this->PointDims,
|
||||
this->Origin,
|
||||
this->Spacing,
|
||||
this->CellWriteOffset,
|
||||
this->PointWriteOffset);
|
||||
ComputePass4X<T> worklet4(
|
||||
isoval, this->PointDims, this->CellWriteOffset, this->PointWriteOffset);
|
||||
invoke(worklet4,
|
||||
metaDataMesh2D,
|
||||
metaDataSums,
|
||||
@ -107,6 +96,7 @@ struct launchComputePass4
|
||||
metaDataMax,
|
||||
metaDataNumTris,
|
||||
edgeCases,
|
||||
coordinateSystem,
|
||||
inputField,
|
||||
triangle_topology,
|
||||
sharedState.InterpolationEdgeIds,
|
||||
@ -120,6 +110,7 @@ struct launchComputePass4
|
||||
|
||||
template <typename DeviceAdapterTag,
|
||||
typename T,
|
||||
typename CoordsType,
|
||||
typename StorageTagField,
|
||||
typename MeshSums,
|
||||
typename PointType,
|
||||
@ -127,6 +118,7 @@ struct launchComputePass4
|
||||
VTKM_CONT bool LaunchYAxis(DeviceAdapterTag device,
|
||||
vtkm::Id newPointSize,
|
||||
T isoval,
|
||||
CoordsType coordinateSystem,
|
||||
const vtkm::cont::ArrayHandle<T, StorageTagField>& inputField,
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> edgeCases,
|
||||
vtkm::cont::CellSetStructured<2>& metaDataMesh2D,
|
||||
@ -157,11 +149,8 @@ struct launchComputePass4
|
||||
sharedState.CellIdMap);
|
||||
|
||||
//This needs to be done on array handle view ( start = this->PointWriteOffset, len = newPointSize)
|
||||
ComputePass5Y<T> worklet5(this->PointDims,
|
||||
this->Origin,
|
||||
this->Spacing,
|
||||
this->PointWriteOffset,
|
||||
sharedState.GenerateNormals);
|
||||
ComputePass5Y<T> worklet5(this->PointDims, this->PointWriteOffset, sharedState.GenerateNormals);
|
||||
|
||||
invoke(worklet5,
|
||||
vtkm::cont::make_ArrayHandleView(
|
||||
sharedState.InterpolationEdgeIds, this->PointWriteOffset, newPointSize),
|
||||
@ -169,6 +158,7 @@ struct launchComputePass4
|
||||
sharedState.InterpolationWeights, this->PointWriteOffset, newPointSize),
|
||||
vtkm::cont::make_ArrayHandleView(points, this->PointWriteOffset, newPointSize),
|
||||
inputField,
|
||||
coordinateSystem,
|
||||
normals);
|
||||
|
||||
return true;
|
||||
|
@ -32,9 +32,6 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
{
|
||||
|
||||
vtkm::Id3 PointDims;
|
||||
vtkm::Vec3f Origin;
|
||||
vtkm::Vec3f Spacing;
|
||||
|
||||
T IsoValue;
|
||||
|
||||
vtkm::Id CellWriteOffset;
|
||||
@ -43,13 +40,9 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
ComputePass4X() {}
|
||||
ComputePass4X(T value,
|
||||
const vtkm::Id3& pdims,
|
||||
const vtkm::Vec3f& origin,
|
||||
const vtkm::Vec3f& spacing,
|
||||
vtkm::Id multiContourCellOffset,
|
||||
vtkm::Id multiContourPointOffset)
|
||||
: PointDims(pdims)
|
||||
, Origin(origin)
|
||||
, Spacing(spacing)
|
||||
, IsoValue(value)
|
||||
, CellWriteOffset(multiContourCellOffset)
|
||||
, PointWriteOffset(multiContourPointOffset)
|
||||
@ -62,6 +55,7 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
FieldInPoint axis_maxs,
|
||||
WholeArrayIn cell_tri_count,
|
||||
WholeArrayIn edgeData,
|
||||
WholeArrayIn coords,
|
||||
WholeArrayIn data,
|
||||
WholeArrayOut connectivity,
|
||||
WholeArrayOut edgeIds,
|
||||
@ -69,13 +63,14 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
WholeArrayOut inputCellIds,
|
||||
WholeArrayOut points);
|
||||
using ExecutionSignature =
|
||||
void(ThreadIndices, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, WorkIndex);
|
||||
void(ThreadIndices, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, WorkIndex);
|
||||
|
||||
template <typename ThreadIndices,
|
||||
typename FieldInPointId3,
|
||||
typename FieldInPointId,
|
||||
typename WholeTriField,
|
||||
typename WholeEdgeField,
|
||||
typename WholeCoordsField,
|
||||
typename WholeDataField,
|
||||
typename WholeConnField,
|
||||
typename WholeEdgeIdField,
|
||||
@ -88,6 +83,7 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
const FieldInPointId& axis_maxs,
|
||||
const WholeTriField& cellTriCount,
|
||||
const WholeEdgeField& edges,
|
||||
const WholeCoordsField& coords,
|
||||
const WholeDataField& field,
|
||||
const WholeConnField& conn,
|
||||
const WholeEdgeIdField& interpolatedEdgeIds,
|
||||
@ -141,6 +137,7 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
field,
|
||||
interpolatedEdgeIds,
|
||||
weights,
|
||||
coords,
|
||||
points,
|
||||
state.startPos,
|
||||
increments,
|
||||
@ -158,12 +155,14 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
template <typename WholeDataField,
|
||||
typename WholeIEdgeField,
|
||||
typename WholeWeightField,
|
||||
typename WholeCoordsField,
|
||||
typename WholePointField>
|
||||
VTKM_EXEC inline void Generate(const vtkm::Vec<vtkm::UInt8, 3>& boundaryStatus,
|
||||
const vtkm::Id3& ijk,
|
||||
const WholeDataField& field,
|
||||
const WholeIEdgeField& interpolatedEdgeIds,
|
||||
const WholeWeightField& weights,
|
||||
const WholeCoordsField coords,
|
||||
const WholePointField& points,
|
||||
const vtkm::Id4& startPos,
|
||||
const vtkm::Id3& incs,
|
||||
@ -188,7 +187,7 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
interpolatedEdgeIds.Set(writeIndex, pos);
|
||||
weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
|
||||
|
||||
auto coord = this->InterpolateCoordinate(t, ijk, ijk + vtkm::Id3{ 1, 0, 0 });
|
||||
auto coord = this->InterpolateCoordinate(coords, t, ijk, ijk + vtkm::Id3{ 1, 0, 0 });
|
||||
points.Set(writeIndex, coord);
|
||||
}
|
||||
if (edgeUses[4])
|
||||
@ -201,7 +200,7 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
interpolatedEdgeIds.Set(writeIndex, pos);
|
||||
weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
|
||||
|
||||
auto coord = this->InterpolateCoordinate(t, ijk, ijk + vtkm::Id3{ 0, 1, 0 });
|
||||
auto coord = this->InterpolateCoordinate(coords, t, ijk, ijk + vtkm::Id3{ 0, 1, 0 });
|
||||
points.Set(writeIndex, coord);
|
||||
}
|
||||
if (edgeUses[8])
|
||||
@ -214,7 +213,7 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
interpolatedEdgeIds.Set(writeIndex, pos);
|
||||
weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
|
||||
|
||||
auto coord = this->InterpolateCoordinate(t, ijk, ijk + vtkm::Id3{ 0, 0, 1 });
|
||||
auto coord = this->InterpolateCoordinate(coords, t, ijk, ijk + vtkm::Id3{ 0, 0, 1 });
|
||||
points.Set(writeIndex, coord);
|
||||
}
|
||||
}
|
||||
@ -231,30 +230,30 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
const bool onZ = boundaryStatus[AxisToSum::zindex] & FlyingEdges3D::MaxBoundary;
|
||||
if (onX) //+x boundary
|
||||
{
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 5, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 9, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 5, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 9, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
if (onY) //+x +y
|
||||
{
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 11, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 11, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
}
|
||||
if (onZ) //+x +z
|
||||
{
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 7, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 7, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
}
|
||||
}
|
||||
if (onY) //+y boundary
|
||||
{
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 1, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 10, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 1, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 10, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
if (onZ) //+y +z boundary
|
||||
{
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 3, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 3, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
}
|
||||
}
|
||||
if (onZ) //+z boundary
|
||||
{
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 2, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 6, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 2, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
this->InterpolateEdge(ijk, pos[0], incs, 6, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points);
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
@ -264,6 +263,7 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
template <typename WholeField,
|
||||
typename WholeIEdgeField,
|
||||
typename WholeWeightField,
|
||||
typename WholeCoordsField,
|
||||
typename WholePointField>
|
||||
VTKM_EXEC inline void InterpolateEdge(const vtkm::Id3& ijk,
|
||||
vtkm::Id currentIdx,
|
||||
@ -274,6 +274,7 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
const WholeField& field,
|
||||
const WholeIEdgeField& interpolatedEdgeIds,
|
||||
const WholeWeightField& weights,
|
||||
const WholeCoordsField& coords,
|
||||
const WholePointField& points) const
|
||||
{
|
||||
using AxisToSum = SumXAxis;
|
||||
@ -300,30 +301,49 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
T t = static_cast<T>((this->IsoValue - s0) / (s1 - s0));
|
||||
weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
|
||||
|
||||
auto coord = this->InterpolateCoordinate(t, ijk + offsets1, ijk + offsets2);
|
||||
auto coord = this->InterpolateCoordinate(coords, t, ijk + offsets1, ijk + offsets2);
|
||||
points.Set(writeIndex, coord);
|
||||
}
|
||||
|
||||
// Fast interpolation method for uniform coordinates
|
||||
//----------------------------------------------------------------------------
|
||||
inline VTKM_EXEC vtkm::Vec3f InterpolateCoordinate(T t,
|
||||
const vtkm::Id3& ijk0,
|
||||
const vtkm::Id3& ijk1) const
|
||||
inline VTKM_EXEC vtkm::Vec3f InterpolateCoordinate(
|
||||
vtkm::internal::ArrayPortalUniformPointCoordinates coords,
|
||||
T t,
|
||||
const vtkm::Id3& ijk0,
|
||||
const vtkm::Id3& ijk1) const
|
||||
{
|
||||
return vtkm::Vec3f(
|
||||
this->Origin[0] +
|
||||
this->Spacing[0] *
|
||||
coords.GetOrigin()[0] +
|
||||
coords.GetSpacing()[0] *
|
||||
(static_cast<vtkm::FloatDefault>(ijk0[0]) +
|
||||
static_cast<vtkm::FloatDefault>(t) * static_cast<vtkm::FloatDefault>(ijk1[0] - ijk0[0])),
|
||||
this->Origin[1] +
|
||||
this->Spacing[1] *
|
||||
coords.GetOrigin()[1] +
|
||||
coords.GetSpacing()[1] *
|
||||
(static_cast<vtkm::FloatDefault>(ijk0[1]) +
|
||||
static_cast<vtkm::FloatDefault>(t) * static_cast<vtkm::FloatDefault>(ijk1[1] - ijk0[1])),
|
||||
this->Origin[2] +
|
||||
this->Spacing[2] *
|
||||
coords.GetOrigin()[2] +
|
||||
coords.GetSpacing()[2] *
|
||||
(static_cast<vtkm::FloatDefault>(ijk0[2]) +
|
||||
static_cast<vtkm::FloatDefault>(t) *
|
||||
static_cast<vtkm::FloatDefault>(ijk1[2] - ijk0[2])));
|
||||
}
|
||||
|
||||
// Interpolation for explicit coordinates
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename CoordsPortal>
|
||||
inline VTKM_EXEC vtkm::Vec3f InterpolateCoordinate(CoordsPortal coords,
|
||||
T t,
|
||||
const vtkm::Id3& ijk0,
|
||||
const vtkm::Id3& ijk1) const
|
||||
{
|
||||
return (1.0f - static_cast<vtkm::FloatDefault>(t)) *
|
||||
coords.Get(ijk0[0] + this->PointDims[0] * ijk0[1] +
|
||||
this->PointDims[0] * this->PointDims[1] * ijk0[2]) +
|
||||
static_cast<vtkm::FloatDefault>(t) *
|
||||
coords.Get(ijk1[0] + this->PointDims[0] * ijk1[1] +
|
||||
this->PointDims[0] * this->PointDims[1] * ijk1[2]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,6 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
{
|
||||
|
||||
vtkm::Id3 PointDims;
|
||||
vtkm::Vec3f Origin;
|
||||
vtkm::Vec3f Spacing;
|
||||
|
||||
T IsoValue;
|
||||
|
||||
vtkm::Id CellWriteOffset;
|
||||
@ -42,13 +39,9 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
ComputePass4XWithNormals() {}
|
||||
ComputePass4XWithNormals(T value,
|
||||
const vtkm::Id3& pdims,
|
||||
const vtkm::Vec3f& origin,
|
||||
const vtkm::Vec3f& spacing,
|
||||
vtkm::Id multiContourCellOffset,
|
||||
vtkm::Id multiContourPointOffset)
|
||||
: PointDims(pdims)
|
||||
, Origin(origin)
|
||||
, Spacing(spacing)
|
||||
, IsoValue(value)
|
||||
, CellWriteOffset(multiContourCellOffset)
|
||||
, PointWriteOffset(multiContourPointOffset)
|
||||
@ -61,6 +54,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
FieldInPoint axis_maxs,
|
||||
WholeArrayIn cell_tri_count,
|
||||
WholeArrayIn edgeData,
|
||||
WholeArrayIn coords,
|
||||
WholeArrayIn data,
|
||||
WholeArrayOut connectivity,
|
||||
WholeArrayOut edgeIds,
|
||||
@ -69,13 +63,14 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
WholeArrayOut points,
|
||||
WholeArrayOut normals);
|
||||
using ExecutionSignature =
|
||||
void(ThreadIndices, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, WorkIndex);
|
||||
void(ThreadIndices, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, WorkIndex);
|
||||
|
||||
template <typename ThreadIndices,
|
||||
typename FieldInPointId3,
|
||||
typename FieldInPointId,
|
||||
typename WholeTriField,
|
||||
typename WholeEdgeField,
|
||||
typename WholeCoordsField,
|
||||
typename WholeDataField,
|
||||
typename WholeConnField,
|
||||
typename WholeEdgeIdField,
|
||||
@ -89,6 +84,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
const FieldInPointId& axis_maxs,
|
||||
const WholeTriField& cellTriCount,
|
||||
const WholeEdgeField& edges,
|
||||
const WholeCoordsField& coords,
|
||||
const WholeDataField& field,
|
||||
const WholeConnField& conn,
|
||||
const WholeEdgeIdField& interpolatedEdgeIds,
|
||||
@ -144,6 +140,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
field,
|
||||
interpolatedEdgeIds,
|
||||
weights,
|
||||
coords,
|
||||
points,
|
||||
normals,
|
||||
state.startPos,
|
||||
@ -162,6 +159,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
template <typename WholeDataField,
|
||||
typename WholeIEdgeField,
|
||||
typename WholeWeightField,
|
||||
typename WholeCoordsField,
|
||||
typename WholePointField,
|
||||
typename WholeNormalField>
|
||||
VTKM_EXEC inline void Generate(const vtkm::Vec<vtkm::UInt8, 3>& boundaryStatus,
|
||||
@ -169,6 +167,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
const WholeDataField& field,
|
||||
const WholeIEdgeField& interpolatedEdgeIds,
|
||||
const WholeWeightField& weights,
|
||||
const WholeCoordsField coords,
|
||||
const WholePointField& points,
|
||||
const WholeNormalField& normals,
|
||||
const vtkm::Id4& startPos,
|
||||
@ -197,7 +196,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
|
||||
|
||||
auto ijk1 = ijk + vtkm::Id3{ 1, 0, 0 };
|
||||
auto coord = this->InterpolateCoordinate(t, ijk, ijk1);
|
||||
auto coord = this->InterpolateCoordinate(coords, t, ijk, ijk1);
|
||||
points.Set(writeIndex, coord);
|
||||
|
||||
//gradient generation
|
||||
@ -216,7 +215,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
|
||||
|
||||
auto ijk1 = ijk + vtkm::Id3{ 0, 1, 0 };
|
||||
auto coord = this->InterpolateCoordinate(t, ijk, ijk1);
|
||||
auto coord = this->InterpolateCoordinate(coords, t, ijk, ijk1);
|
||||
points.Set(writeIndex, coord);
|
||||
|
||||
//gradient generation
|
||||
@ -235,7 +234,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
|
||||
|
||||
auto ijk1 = ijk + vtkm::Id3{ 0, 0, 1 };
|
||||
auto coord = this->InterpolateCoordinate(t, ijk, ijk1);
|
||||
auto coord = this->InterpolateCoordinate(coords, t, ijk, ijk1);
|
||||
points.Set(writeIndex, coord);
|
||||
|
||||
//gradient generation
|
||||
@ -258,38 +257,38 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
if (onX) //+x boundary
|
||||
{
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 5, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 5, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 9, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 9, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
if (onY) //+x +y
|
||||
{
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 11, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 11, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
}
|
||||
if (onZ) //+x +z
|
||||
{
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 7, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 7, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
}
|
||||
}
|
||||
if (onY) //+y boundary
|
||||
{
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 1, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 1, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 10, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 10, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
if (onZ) //+y +z boundary
|
||||
{
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 3, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 3, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
}
|
||||
}
|
||||
if (onZ) //+z boundary
|
||||
{
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 2, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 2, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
this->InterpolateEdge(
|
||||
fullyInterior, ijk, pos[0], incs, 6, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, points, normals);
|
||||
fullyInterior, ijk, pos[0], incs, 6, edgeUses, edgeIds, field, interpolatedEdgeIds, weights, coords, points, normals);
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
@ -300,6 +299,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
typename WholeIEdgeField,
|
||||
typename WholeWeightField,
|
||||
typename WholePointField,
|
||||
typename WholeCoordsField,
|
||||
typename WholeNormalField>
|
||||
VTKM_EXEC inline void InterpolateEdge(bool fullyInterior,
|
||||
const vtkm::Id3& ijk,
|
||||
@ -311,6 +311,7 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
const WholeField& field,
|
||||
const WholeIEdgeField& interpolatedEdgeIds,
|
||||
const WholeWeightField& weights,
|
||||
const WholeCoordsField& coords,
|
||||
const WholePointField& points,
|
||||
const WholeNormalField& normals) const
|
||||
{
|
||||
@ -338,36 +339,55 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi
|
||||
T t = static_cast<T>((this->IsoValue - s0) / (s1 - s0));
|
||||
weights.Set(writeIndex, static_cast<vtkm::FloatDefault>(t));
|
||||
|
||||
auto coord = this->InterpolateCoordinate(t, ijk + offsets1, ijk + offsets2);
|
||||
auto coord = this->InterpolateCoordinate(coords, t, ijk + offsets1, ijk + offsets2);
|
||||
points.Set(writeIndex, coord);
|
||||
|
||||
auto g0 = this->ComputeGradient(fullyInterior, ijk + offsets1, incs, iEdge[0], field);
|
||||
auto g1 = this->ComputeGradient(fullyInterior, ijk + offsets2, incs, iEdge[1], field);
|
||||
auto g0 = this->ComputeGradient(fullyInterior, ijk + offsets1, incs, iEdge[0], field);
|
||||
g1 = g0 + (t * (g1 - g0));
|
||||
normals.Set(writeIndex, vtkm::Normal(g1));
|
||||
}
|
||||
|
||||
// Fast interpolation method for uniform coordinates
|
||||
//----------------------------------------------------------------------------
|
||||
inline VTKM_EXEC vtkm::Vec3f InterpolateCoordinate(T t,
|
||||
const vtkm::Id3& ijk0,
|
||||
const vtkm::Id3& ijk1) const
|
||||
inline VTKM_EXEC vtkm::Vec3f InterpolateCoordinate(
|
||||
const vtkm::internal::ArrayPortalUniformPointCoordinates& coords,
|
||||
T t,
|
||||
const vtkm::Id3& ijk0,
|
||||
const vtkm::Id3& ijk1) const
|
||||
{
|
||||
return vtkm::Vec3f(
|
||||
this->Origin[0] +
|
||||
this->Spacing[0] *
|
||||
coords.GetOrigin()[0] +
|
||||
coords.GetSpacing()[0] *
|
||||
(static_cast<vtkm::FloatDefault>(ijk0[0]) +
|
||||
static_cast<vtkm::FloatDefault>(t) * static_cast<vtkm::FloatDefault>(ijk1[0] - ijk0[0])),
|
||||
this->Origin[1] +
|
||||
this->Spacing[1] *
|
||||
coords.GetOrigin()[1] +
|
||||
coords.GetSpacing()[1] *
|
||||
(static_cast<vtkm::FloatDefault>(ijk0[1]) +
|
||||
static_cast<vtkm::FloatDefault>(t) * static_cast<vtkm::FloatDefault>(ijk1[1] - ijk0[1])),
|
||||
this->Origin[2] +
|
||||
this->Spacing[2] *
|
||||
coords.GetOrigin()[2] +
|
||||
coords.GetSpacing()[2] *
|
||||
(static_cast<vtkm::FloatDefault>(ijk0[2]) +
|
||||
static_cast<vtkm::FloatDefault>(t) *
|
||||
static_cast<vtkm::FloatDefault>(ijk1[2] - ijk0[2])));
|
||||
}
|
||||
|
||||
// Interpolation for explicit coordinates
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename CoordsPortal>
|
||||
inline VTKM_EXEC vtkm::Vec3f InterpolateCoordinate(const CoordsPortal& coords,
|
||||
T t,
|
||||
const vtkm::Id3& ijk0,
|
||||
const vtkm::Id3& ijk1) const
|
||||
{
|
||||
return (1.0f - static_cast<vtkm::FloatDefault>(t)) *
|
||||
coords.Get(ijk0[0] + this->PointDims[0] * ijk0[1] +
|
||||
this->PointDims[0] * this->PointDims[1] * ijk0[2]) +
|
||||
static_cast<vtkm::FloatDefault>(t) *
|
||||
coords.Get(ijk1[0] + this->PointDims[0] * ijk1[1] +
|
||||
this->PointDims[0] * this->PointDims[1] * ijk1[2]);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <typename WholeDataField>
|
||||
VTKM_EXEC vtkm::Vec3f ComputeGradient(bool fullyInterior,
|
||||
|
@ -276,17 +276,11 @@ struct ComputePass4Y : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
template <typename T>
|
||||
struct ComputePass5Y : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
|
||||
vtkm::internal::ArrayPortalUniformPointCoordinates Coordinates;
|
||||
vtkm::Id3 PointDims;
|
||||
vtkm::Id NormalWriteOffset;
|
||||
|
||||
ComputePass5Y() {}
|
||||
ComputePass5Y(const vtkm::Id3& pdims,
|
||||
const vtkm::Vec3f& origin,
|
||||
const vtkm::Vec3f& spacing,
|
||||
vtkm::Id normalWriteOffset,
|
||||
bool generateNormals)
|
||||
: Coordinates(pdims, origin, spacing)
|
||||
ComputePass5Y(const vtkm::Id3& pdims, vtkm::Id normalWriteOffset, bool generateNormals)
|
||||
: PointDims(pdims)
|
||||
, NormalWriteOffset(normalWriteOffset)
|
||||
{
|
||||
if (!generateNormals)
|
||||
@ -299,20 +293,25 @@ struct ComputePass5Y : public vtkm::worklet::WorkletMapField
|
||||
FieldIn interpWeight,
|
||||
FieldOut points,
|
||||
WholeArrayIn field,
|
||||
WholeArrayIn coords,
|
||||
WholeArrayOut normals);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, WorkIndex);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, WorkIndex);
|
||||
|
||||
template <typename PT, typename WholeInputField, typename WholeNormalField>
|
||||
template <typename PT,
|
||||
typename WholeInputField,
|
||||
typename WholeNormalField,
|
||||
typename WholeCoordsField>
|
||||
VTKM_EXEC void operator()(const vtkm::Id2& interpEdgeIds,
|
||||
vtkm::FloatDefault weight,
|
||||
vtkm::Vec<PT, 3>& outPoint,
|
||||
const WholeInputField& field,
|
||||
const WholeCoordsField& coords,
|
||||
WholeNormalField& normals,
|
||||
vtkm::Id oidx) const
|
||||
{
|
||||
{
|
||||
vtkm::Vec3f point1 = this->Coordinates.Get(interpEdgeIds[0]);
|
||||
vtkm::Vec3f point2 = this->Coordinates.Get(interpEdgeIds[1]);
|
||||
vtkm::Vec3f point1 = coords.Get(interpEdgeIds[0]);
|
||||
vtkm::Vec3f point2 = coords.Get(interpEdgeIds[1]);
|
||||
outPoint = vtkm::Lerp(point1, point2, weight);
|
||||
}
|
||||
|
||||
@ -320,15 +319,13 @@ struct ComputePass5Y : public vtkm::worklet::WorkletMapField
|
||||
if (this->NormalWriteOffset >= 0)
|
||||
{
|
||||
vtkm::Vec<T, 3> g0, g1;
|
||||
const vtkm::Id3& dims = this->Coordinates.GetDimensions();
|
||||
vtkm::Id3 ijk{ interpEdgeIds[0] % dims[0],
|
||||
(interpEdgeIds[0] / dims[0]) % dims[1],
|
||||
interpEdgeIds[0] / (dims[0] * dims[1]) };
|
||||
vtkm::Id3 ijk{ interpEdgeIds[0] % this->PointDims[0],
|
||||
(interpEdgeIds[0] / this->PointDims[0]) % this->PointDims[1],
|
||||
interpEdgeIds[0] / (this->PointDims[0] * this->PointDims[1]) };
|
||||
|
||||
vtkm::worklet::gradient::StructuredPointGradient gradient;
|
||||
vtkm::exec::BoundaryState boundary(ijk, dims);
|
||||
vtkm::exec::FieldNeighborhood<vtkm::internal::ArrayPortalUniformPointCoordinates>
|
||||
coord_neighborhood(this->Coordinates, boundary);
|
||||
vtkm::exec::BoundaryState boundary(ijk, this->PointDims);
|
||||
vtkm::exec::FieldNeighborhood<WholeCoordsField> coord_neighborhood(coords, boundary);
|
||||
|
||||
vtkm::exec::FieldNeighborhood<WholeInputField> field_neighborhood(field, boundary);
|
||||
|
||||
@ -337,9 +334,9 @@ struct ComputePass5Y : public vtkm::worklet::WorkletMapField
|
||||
gradient(boundary, coord_neighborhood, field_neighborhood, g0);
|
||||
|
||||
//compute the gradient at point 2. This optimization can be optimized
|
||||
boundary.IJK = vtkm::Id3{ interpEdgeIds[1] % dims[0],
|
||||
(interpEdgeIds[1] / dims[0]) % dims[1],
|
||||
interpEdgeIds[1] / (dims[0] * dims[1]) };
|
||||
boundary.IJK = vtkm::Id3{ interpEdgeIds[1] % this->PointDims[0],
|
||||
(interpEdgeIds[1] / this->PointDims[0]) % this->PointDims[1],
|
||||
interpEdgeIds[1] / (this->PointDims[0] * this->PointDims[1]) };
|
||||
gradient(boundary, coord_neighborhood, field_neighborhood, g1);
|
||||
|
||||
vtkm::Vec3f n = vtkm::Lerp(g0, g1, weight);
|
||||
|
@ -234,7 +234,7 @@ void TestWithStructuredData()
|
||||
contour.SetIsoValue(192);
|
||||
contour.SetMergeDuplicatePoints(true);
|
||||
contour.SetGenerateNormals(true);
|
||||
contour.SetComputeFastNormalsForStructured(true);
|
||||
contour.SetComputeFastNormals(true);
|
||||
contour.SetNormalArrayName("normals");
|
||||
dataSet = contour.Execute(dataSet);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user