mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge branch 'master' of https://gitlab.kitware.com/vtk/vtk-m
This commit is contained in:
commit
51435f2277
@ -117,6 +117,10 @@ stages:
|
|||||||
variables:
|
variables:
|
||||||
CMAKE_VERSION: "3.13.5"
|
CMAKE_VERSION: "3.13.5"
|
||||||
|
|
||||||
|
.warning_policy:
|
||||||
|
allow_failure:
|
||||||
|
exit_codes: [ 47 ]
|
||||||
|
|
||||||
.install_cmake: &install_cmake |
|
.install_cmake: &install_cmake |
|
||||||
export PATH=$PWD/.gitlab/cmake/bin:$PATH
|
export PATH=$PWD/.gitlab/cmake/bin:$PATH
|
||||||
.gitlab/ci/config/cmake.sh "$CMAKE_VERSION"
|
.gitlab/ci/config/cmake.sh "$CMAKE_VERSION"
|
||||||
@ -141,8 +145,10 @@ stages:
|
|||||||
script:
|
script:
|
||||||
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
|
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
|
||||||
- sccache --show-stats
|
- sccache --show-stats
|
||||||
|
- cmake -P .gitlab/ci/check_warnings.cmake || exit 47
|
||||||
extends:
|
extends:
|
||||||
- .cmake_build_artifacts
|
- .cmake_build_artifacts
|
||||||
|
- .warning_policy
|
||||||
|
|
||||||
.cmake_test_linux: &cmake_test_linux
|
.cmake_test_linux: &cmake_test_linux
|
||||||
stage: test
|
stage: test
|
||||||
@ -192,6 +198,7 @@ stages:
|
|||||||
# CTest and CMake install files.
|
# CTest and CMake install files.
|
||||||
# Note: this also captures our CIState.cmake file
|
# Note: this also captures our CIState.cmake file
|
||||||
- build/CMakeCache.txt
|
- build/CMakeCache.txt
|
||||||
|
- build/compile_num_warnings.log
|
||||||
- build/**/*.cmake
|
- build/**/*.cmake
|
||||||
- build/Testing/
|
- build/Testing/
|
||||||
|
|
||||||
|
31
.gitlab/ci/check_warnings.cmake
Normal file
31
.gitlab/ci/check_warnings.cmake
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
##=============================================================================
|
||||||
|
##
|
||||||
|
## Copyright (c) Kitware, Inc.
|
||||||
|
## All rights reserved.
|
||||||
|
## See LICENSE.txt for details.
|
||||||
|
##
|
||||||
|
## This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
## PURPOSE. See the above copyright notice for more information.
|
||||||
|
##
|
||||||
|
##=============================================================================
|
||||||
|
|
||||||
|
# Find the path 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})
|
||||||
|
|
||||||
|
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()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# `compile_num_warnings` contains a single integer symbolizing the number of
|
||||||
|
# warnings of the last build.
|
||||||
|
set(bld_log_path "${CMAKE_SOURCE_DIR}/build/compile_num_warnings.log")
|
||||||
|
file(STRINGS "${bld_log_path}" output)
|
||||||
|
if (NOT "${output}" STREQUAL "0")
|
||||||
|
message(FATAL_ERROR "Build warnings detected, please check cdash-commit job")
|
||||||
|
endif()
|
@ -91,25 +91,19 @@ foreach(option IN LISTS options)
|
|||||||
set(VTKm_ENABLE_HDF5_IO "ON" CACHE STRING "")
|
set(VTKm_ENABLE_HDF5_IO "ON" CACHE STRING "")
|
||||||
|
|
||||||
elseif(maxwell STREQUAL option)
|
elseif(maxwell STREQUAL option)
|
||||||
set(VTKm_CUDA_Architecture "maxwell" CACHE STRING "")
|
set(vtkm_cuda_arch "maxwell")
|
||||||
|
|
||||||
elseif(pascal STREQUAL option)
|
elseif(pascal STREQUAL option)
|
||||||
set(VTKm_CUDA_Architecture "pascal" CACHE STRING "")
|
set(vtkm_cuda_arch "pascal")
|
||||||
|
|
||||||
elseif(volta STREQUAL option)
|
elseif(volta STREQUAL option)
|
||||||
set(VTKm_CUDA_Architecture "volta" CACHE STRING "")
|
set(vtkm_cuda_arch "volta")
|
||||||
|
|
||||||
# From turing we set the architecture using the cannonical
|
|
||||||
# CMAKE_CUDA_ARCHITECTURES
|
|
||||||
elseif(turing STREQUAL option)
|
elseif(turing STREQUAL option)
|
||||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
|
set(vtkm_cuda_arch "turing")
|
||||||
set(CMAKE_CUDA_ARCHITECTURES "75" CACHE STRING "")
|
|
||||||
else()
|
|
||||||
set(VTKm_CUDA_Architecture "turing" CACHE STRING "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
elseif(ampere STREQUAL option)
|
elseif(ampere STREQUAL option)
|
||||||
set(CMAKE_CUDA_ARCHITECTURES "80" CACHE STRING "")
|
set(vtkm_cuda_arch "ampere")
|
||||||
|
|
||||||
elseif(hip STREQUAL option)
|
elseif(hip STREQUAL option)
|
||||||
if(CMAKE_VERSION VERSION_LESS_EQUAL 3.20)
|
if(CMAKE_VERSION VERSION_LESS_EQUAL 3.20)
|
||||||
@ -187,3 +181,22 @@ endif()
|
|||||||
if(sanitizers)
|
if(sanitizers)
|
||||||
set(VTKm_USE_SANITIZER "${sanitizers}" CACHE STRING "" FORCE)
|
set(VTKm_USE_SANITIZER "${sanitizers}" CACHE STRING "" FORCE)
|
||||||
endif()
|
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()
|
||||||
|
@ -19,7 +19,7 @@ curl -L "https://github.com/kokkos/kokkos/archive/refs/tags/$VERSION.tar.gz" \
|
|||||||
cmake -S "$WORKDIR/kokkos-$VERSION" -B "$WORKDIR/kokkos_build" \
|
cmake -S "$WORKDIR/kokkos-$VERSION" -B "$WORKDIR/kokkos_build" \
|
||||||
"-DCMAKE_BUILD_TYPE:STRING=release" \
|
"-DCMAKE_BUILD_TYPE:STRING=release" \
|
||||||
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache" \
|
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache" \
|
||||||
"-DCMAKE_CXX_STANDARD:STRING=14" \
|
"-DCMAKE_CXX_STANDARD:STRING=17" \
|
||||||
"-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON" \
|
"-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON" \
|
||||||
"-DKokkos_ENABLE_HIP:BOOL=ON" \
|
"-DKokkos_ENABLE_HIP:BOOL=ON" \
|
||||||
"-DKokkos_ENABLE_HIP_RELOCATABLE_DEVICE_CODE:BOOL=OFF" \
|
"-DKokkos_ENABLE_HIP_RELOCATABLE_DEVICE_CODE:BOOL=OFF" \
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
# Ad-hoc build that runs in the ECP Hardware, concretely in OLCF Spock.
|
# Ad-hoc build that runs in the ECP Hardware, concretely in OLCF Spock.
|
||||||
.crusher_gcc_hip:
|
.crusher_gcc_hip:
|
||||||
variables:
|
variables:
|
||||||
CCACHE_BASEDIR: "/gpfs/alpine/csc331/scratch/"
|
CCACHE_BASEDIR: "/lustre/orion/csc331/scratch/"
|
||||||
CCACHE_DIR: "/gpfs/alpine/csc331/scratch/vbolea/ci/vtk-m/ccache"
|
CCACHE_DIR: "/lustre/orion/csc331/scratch/vbolea/ci/vtk-m/ccache"
|
||||||
CUSTOM_CI_BUILDS_DIR: "/gpfs/alpine/csc331/scratch/vbolea/ci/vtk-m/runtime"
|
CUSTOM_CI_BUILDS_DIR: "/lustre/orion/csc331/scratch/vbolea/ci/vtk-m/runtime"
|
||||||
|
|
||||||
# -isystem= is not affected by CCACHE_BASEDIR, thus we must ignore it
|
# -isystem= is not affected by CCACHE_BASEDIR, thus we must ignore it
|
||||||
CCACHE_IGNOREOPTIONS: "-isystem=*"
|
CCACHE_IGNOREOPTIONS: "-isystem=*"
|
||||||
@ -14,18 +14,21 @@
|
|||||||
CMAKE_GENERATOR: "Ninja"
|
CMAKE_GENERATOR: "Ninja"
|
||||||
CMAKE_PREFIX_PATH: "$CI_BUILDS_DIR/kokkos_install"
|
CMAKE_PREFIX_PATH: "$CI_BUILDS_DIR/kokkos_install"
|
||||||
|
|
||||||
|
# We do not want to use the user's ~/.gitconfig
|
||||||
|
GIT_CONFIG_GLOBAL: "true"
|
||||||
|
|
||||||
KOKKOS_OPTS: >-
|
KOKKOS_OPTS: >-
|
||||||
-DCMAKE_INSTALL_PREFIX:PATH=$CI_BUILDS_DIR/kokkos_install
|
-DCMAKE_INSTALL_PREFIX:PATH=$CI_BUILDS_DIR/kokkos_install
|
||||||
-DCMAKE_CXX_COMPILER:FILEPATH=/opt/rocm-4.5.0/hip/bin/hipcc
|
-DCMAKE_CXX_COMPILER:FILEPATH=/opt/rocm-5.4.3/hip/bin/hipcc
|
||||||
-DKokkos_ARCH_VEGA90A:BOOL=ON
|
-DKokkos_ARCH_VEGA90A:BOOL=ON
|
||||||
|
|
||||||
# DefApps/default;craype;rocm;gcc should be loaded first
|
# The user default module list should not exist
|
||||||
|
# craype;rocm;gcc should be loaded first
|
||||||
JOB_MODULES: >-
|
JOB_MODULES: >-
|
||||||
DefApps/default
|
|
||||||
craype-accel-amd-gfx90a
|
craype-accel-amd-gfx90a
|
||||||
rocm/4.5.0
|
|
||||||
gcc/12
|
gcc/12
|
||||||
cmake/3.23
|
cmake
|
||||||
|
rocm/5.4.3
|
||||||
git
|
git
|
||||||
git-lfs
|
git-lfs
|
||||||
ninja
|
ninja
|
||||||
|
@ -30,11 +30,10 @@ if(NOT DEFINED ENV{GITLAB_CI_EMULATION})
|
|||||||
else()
|
else()
|
||||||
ctest_submit(PARTS Build)
|
ctest_submit(PARTS Build)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
file(WRITE "${CTEST_BINARY_DIRECTORY}/compile_num_warnings.log" "${num_warnings}")
|
||||||
|
|
||||||
if (build_result)
|
if (build_result)
|
||||||
message(FATAL_ERROR
|
message(FATAL_ERROR "Failed to build")
|
||||||
"Failed to build")
|
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -25,6 +25,7 @@ test:macos_xcode13:
|
|||||||
CC: gcc
|
CC: gcc
|
||||||
CXX: g++
|
CXX: g++
|
||||||
DEVELOPER_DIR: "/Applications/Xcode-13.3.app/Contents/Developer"
|
DEVELOPER_DIR: "/Applications/Xcode-13.3.app/Contents/Developer"
|
||||||
|
GIT_CLONE_PATH: "$CI_BUILDS_DIR/vtk-m-ci"
|
||||||
VTKM_SETTINGS: "64bit_floats+shared+ccache"
|
VTKM_SETTINGS: "64bit_floats+shared+ccache"
|
||||||
|
|
||||||
.cmake_build_macos:
|
.cmake_build_macos:
|
||||||
@ -55,11 +56,13 @@ test:macos_xcode13:
|
|||||||
- "ctest -VV -S .gitlab/ci/ctest_configure.cmake"
|
- "ctest -VV -S .gitlab/ci/ctest_configure.cmake"
|
||||||
script:
|
script:
|
||||||
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
|
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
|
||||||
|
- cmake -P .gitlab/ci/check_warnings.cmake || exit 47
|
||||||
after_script:
|
after_script:
|
||||||
- ccache -v -s
|
- ccache -v -s
|
||||||
- ccache -z
|
- ccache -z
|
||||||
extends:
|
extends:
|
||||||
- .cmake_build_artifacts
|
- .cmake_build_artifacts
|
||||||
|
- .warning_policy
|
||||||
|
|
||||||
.cmake_test_macos:
|
.cmake_test_macos:
|
||||||
stage: test
|
stage: test
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
variables:
|
variables:
|
||||||
VCVARSALL: "${VS160COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
|
VCVARSALL: "${VS160COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
|
||||||
VCVARSPLATFORM: "x64"
|
VCVARSPLATFORM: "x64"
|
||||||
VCVARSVERSION: "14.25"
|
VCVARSVERSION: "14.28.29333"
|
||||||
|
|
||||||
.cmake_build_windows: &cmake_build_windows
|
.cmake_build_windows: &cmake_build_windows
|
||||||
extends:
|
extends:
|
||||||
@ -40,6 +40,8 @@
|
|||||||
- "ctest -VV -S .gitlab/ci/ctest_configure.cmake"
|
- "ctest -VV -S .gitlab/ci/ctest_configure.cmake"
|
||||||
script:
|
script:
|
||||||
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
|
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
|
||||||
|
- "cmake -P .gitlab/ci/check_warnings.cmake"
|
||||||
|
- if (!$?) { $host.SetShouldExit(47); exit 47 }
|
||||||
after_script:
|
after_script:
|
||||||
# This is needed since sometimes this process hangs holding files
|
# This is needed since sometimes this process hangs holding files
|
||||||
# in the build directory. Blocking new builds
|
# in the build directory. Blocking new builds
|
||||||
@ -58,6 +60,7 @@
|
|||||||
# CTest and CMake install files.
|
# CTest and CMake install files.
|
||||||
# Note: this also captures our CIState.cmake file
|
# Note: this also captures our CIState.cmake file
|
||||||
- build/CMakeCache.txt
|
- build/CMakeCache.txt
|
||||||
|
- build/compile_num_warnings.log
|
||||||
- build/**/*.cmake
|
- build/**/*.cmake
|
||||||
- build/Testing/
|
- build/Testing/
|
||||||
|
|
||||||
@ -98,6 +101,7 @@ build:windows_vs2019:
|
|||||||
extends:
|
extends:
|
||||||
- .cmake_build_windows
|
- .cmake_build_windows
|
||||||
- .run_automatically
|
- .run_automatically
|
||||||
|
- .warning_policy
|
||||||
variables:
|
variables:
|
||||||
CMAKE_GENERATOR: "Ninja"
|
CMAKE_GENERATOR: "Ninja"
|
||||||
CMAKE_BUILD_TYPE: Release
|
CMAKE_BUILD_TYPE: Release
|
||||||
|
@ -438,8 +438,7 @@ void BenchContour(::benchmark::State& state)
|
|||||||
|
|
||||||
filter.SetMergeDuplicatePoints(mergePoints);
|
filter.SetMergeDuplicatePoints(mergePoints);
|
||||||
filter.SetGenerateNormals(normals);
|
filter.SetGenerateNormals(normals);
|
||||||
filter.SetComputeFastNormalsForStructured(fastNormals);
|
filter.SetComputeFastNormals(fastNormals);
|
||||||
filter.SetComputeFastNormalsForUnstructured(fastNormals);
|
|
||||||
|
|
||||||
vtkm::cont::Timer timer{ device };
|
vtkm::cont::Timer timer{ device };
|
||||||
|
|
||||||
|
@ -340,8 +340,7 @@ void BenchContour(::benchmark::State& state)
|
|||||||
filter.SetActiveField(PointScalarsName, vtkm::cont::Field::Association::Points);
|
filter.SetActiveField(PointScalarsName, vtkm::cont::Field::Association::Points);
|
||||||
filter.SetMergeDuplicatePoints(true);
|
filter.SetMergeDuplicatePoints(true);
|
||||||
filter.SetGenerateNormals(true);
|
filter.SetGenerateNormals(true);
|
||||||
filter.SetComputeFastNormalsForStructured(true);
|
filter.SetComputeFastNormals(true);
|
||||||
filter.SetComputeFastNormalsForUnstructured(true);
|
|
||||||
state.ResumeTiming(); // And resume timers.
|
state.ResumeTiming(); // And resume timers.
|
||||||
|
|
||||||
filterTimer.Start();
|
filterTimer.Start();
|
||||||
|
3
data/baseline/rendering/volume/rectilinear3D_cell.png
Normal file
3
data/baseline/rendering/volume/rectilinear3D_cell.png
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:f351663534f154eec2b09c1bb18f367a204a0665468655ad782281837b10c52b
|
||||||
|
size 128759
|
3
data/baseline/rendering/volume/uniform.png
Normal file
3
data/baseline/rendering/volume/uniform.png
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9700359c5a3a562660dcf07126ffd1402296c08318efb51bbf660e05a4d9d7da
|
||||||
|
size 126832
|
3
data/baseline/rendering/volume/uniform_cell.png
Normal file
3
data/baseline/rendering/volume/uniform_cell.png
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:6ae8423ce77f432c01c7cce4df74b378e5c2d40ec8db1a791644de1ff205c85a
|
||||||
|
size 147084
|
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`.
|
3
docs/changelog/tetrahedralize-triangulate-check.md
Normal file
3
docs/changelog/tetrahedralize-triangulate-check.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Tetrahedralize and Triangulate filters now check if the input is already tetrahedral/triangular
|
||||||
|
|
||||||
|
Previously, tetrahedralize/triangulate would blindly convert all the cells to tetrahedra/triangles, even when they were already. Now, the dataset is directly returned if the CellSet is a CellSetSingleType of tetras/triangles, and no further processing is done in the worklets for CellSetExplicit when all shapes are tetras or triangles.
|
@ -200,7 +200,10 @@ struct GetTypeInParentheses<void(T)>
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
using ValueType = typename__ Superclass::ValueType; \
|
using ValueType = typename__ Superclass::ValueType; \
|
||||||
using StorageTag = typename__ Superclass::StorageTag
|
using StorageTag = typename__ Superclass::StorageTag; \
|
||||||
|
using StorageType = typename__ Superclass::StorageType; \
|
||||||
|
using ReadPortalType = typename__ Superclass::ReadPortalType; \
|
||||||
|
using WritePortalType = typename__ Superclass::WritePortalType
|
||||||
|
|
||||||
/// \brief Macro to make default methods in ArrayHandle subclasses.
|
/// \brief Macro to make default methods in ArrayHandle subclasses.
|
||||||
///
|
///
|
||||||
|
@ -344,10 +344,6 @@ public:
|
|||||||
SecondHandleType,
|
SecondHandleType,
|
||||||
ThirdHandleType>::Superclass));
|
ThirdHandleType>::Superclass));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleCartesianProduct(const FirstHandleType& firstArray,
|
ArrayHandleCartesianProduct(const FirstHandleType& firstArray,
|
||||||
const SecondHandleType& secondArray,
|
const SecondHandleType& secondArray,
|
||||||
|
@ -188,7 +188,6 @@ struct CompositeVectorTraits
|
|||||||
|
|
||||||
using ValueType = typename vtkm::internal::compvec::GetValueType<ArrayTs...>::ValueType;
|
using ValueType = typename vtkm::internal::compvec::GetValueType<ArrayTs...>::ValueType;
|
||||||
using StorageTag = vtkm::cont::StorageTagCompositeVec<typename ArrayTs::StorageTag...>;
|
using StorageTag = vtkm::cont::StorageTagCompositeVec<typename ArrayTs::StorageTag...>;
|
||||||
using StorageType = Storage<ValueType, StorageTag>;
|
|
||||||
using Superclass = ArrayHandle<ValueType, StorageTag>;
|
using Superclass = ArrayHandle<ValueType, StorageTag>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -400,14 +399,10 @@ class ArrayHandleCompositeVector
|
|||||||
: public ArrayHandle<typename internal::CompositeVectorTraits<ArrayTs...>::ValueType,
|
: public ArrayHandle<typename internal::CompositeVectorTraits<ArrayTs...>::ValueType,
|
||||||
typename internal::CompositeVectorTraits<ArrayTs...>::StorageTag>
|
typename internal::CompositeVectorTraits<ArrayTs...>::StorageTag>
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
using Traits = internal::CompositeVectorTraits<ArrayTs...>;
|
|
||||||
using StorageType = typename Traits::StorageType;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleCompositeVector,
|
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleCompositeVector,
|
||||||
(ArrayHandleCompositeVector<ArrayTs...>),
|
(ArrayHandleCompositeVector<ArrayTs...>),
|
||||||
(typename Traits::Superclass));
|
(typename internal::CompositeVectorTraits<ArrayTs...>::Superclass));
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleCompositeVector(const ArrayTs&... arrays)
|
ArrayHandleCompositeVector(const ArrayTs&... arrays)
|
||||||
|
@ -251,10 +251,6 @@ public:
|
|||||||
StorageTagConcatenate<typename ArrayHandleType1::StorageTag,
|
StorageTagConcatenate<typename ArrayHandleType1::StorageTag,
|
||||||
typename ArrayHandleType2::StorageTag>>));
|
typename ArrayHandleType2::StorageTag>>));
|
||||||
|
|
||||||
protected:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleConcatenate(const ArrayHandleType1& array1, const ArrayHandleType2& array2)
|
ArrayHandleConcatenate(const ArrayHandleType1& array1, const ArrayHandleType2& array2)
|
||||||
: Superclass(StorageType::CreateBuffers(array1, array2))
|
: Superclass(StorageType::CreateBuffers(array1, array2))
|
||||||
|
@ -565,7 +565,6 @@ struct DecoratorHandleTraits
|
|||||||
using StorageTraits = decor::DecoratorStorageTraits<DecoratorImplT, ArrayTs...>;
|
using StorageTraits = decor::DecoratorStorageTraits<DecoratorImplT, ArrayTs...>;
|
||||||
using ValueType = typename StorageTraits::ValueType;
|
using ValueType = typename StorageTraits::ValueType;
|
||||||
using StorageTag = StorageTagDecorator<DecoratorImplT, ArrayTs...>;
|
using StorageTag = StorageTagDecorator<DecoratorImplT, ArrayTs...>;
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
using Superclass = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
|
using Superclass = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -651,7 +650,6 @@ class ArrayHandleDecorator
|
|||||||
private:
|
private:
|
||||||
using Traits = internal::DecoratorHandleTraits<typename std::decay<DecoratorImplT>::type,
|
using Traits = internal::DecoratorHandleTraits<typename std::decay<DecoratorImplT>::type,
|
||||||
typename std::decay<ArrayTs>::type...>;
|
typename std::decay<ArrayTs>::type...>;
|
||||||
using StorageType = typename Traits::StorageType;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleDecorator,
|
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleDecorator,
|
||||||
|
@ -94,8 +94,7 @@ class Storage<typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::Com
|
|||||||
{
|
{
|
||||||
using SourceValueType = typename ArrayHandleType::ValueType;
|
using SourceValueType = typename ArrayHandleType::ValueType;
|
||||||
using ValueType = typename vtkm::VecTraits<SourceValueType>::ComponentType;
|
using ValueType = typename vtkm::VecTraits<SourceValueType>::ComponentType;
|
||||||
using SourceStorageTag = typename ArrayHandleType::StorageTag;
|
using SourceStorage = typename ArrayHandleType::StorageType;
|
||||||
using SourceStorage = vtkm::cont::internal::Storage<SourceValueType, SourceStorageTag>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VTKM_CONT static vtkm::IdComponent ComponentIndex(
|
VTKM_CONT static vtkm::IdComponent ComponentIndex(
|
||||||
@ -198,10 +197,6 @@ public:
|
|||||||
typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::ComponentType,
|
typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::ComponentType,
|
||||||
StorageTagExtractComponent<ArrayHandleType>>));
|
StorageTagExtractComponent<ArrayHandleType>>));
|
||||||
|
|
||||||
protected:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleExtractComponent(const ArrayHandleType& array, vtkm::IdComponent component)
|
ArrayHandleExtractComponent(const ArrayHandleType& array, vtkm::IdComponent component)
|
||||||
: Superclass(StorageType::CreateBuffers(component, array))
|
: Superclass(StorageType::CreateBuffers(component, array))
|
||||||
|
@ -285,10 +285,6 @@ public:
|
|||||||
|
|
||||||
using ComponentType = typename ComponentsArrayHandleType::ValueType;
|
using ComponentType = typename ComponentsArrayHandleType::ValueType;
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleGroupVecVariable(const ComponentsArrayHandleType& componentsArray,
|
ArrayHandleGroupVecVariable(const ComponentsArrayHandleType& componentsArray,
|
||||||
const OffsetsArrayHandleType& offsetsArray)
|
const OffsetsArrayHandleType& offsetsArray)
|
||||||
|
@ -158,7 +158,6 @@ struct ArrayHandleImplicitTraits
|
|||||||
using PortalType = vtkm::internal::ArrayPortalImplicit<FunctorType>;
|
using PortalType = vtkm::internal::ArrayPortalImplicit<FunctorType>;
|
||||||
using StorageTag = vtkm::cont::StorageTagImplicit<PortalType>;
|
using StorageTag = vtkm::cont::StorageTagImplicit<PortalType>;
|
||||||
using Superclass = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
|
using Superclass = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
@ -408,10 +408,6 @@ public:
|
|||||||
(ArrayHandleMultiplexer<ArrayHandleTypes...>),
|
(ArrayHandleMultiplexer<ArrayHandleTypes...>),
|
||||||
(vtkm::cont::ArrayHandle<typename Traits::ValueType, typename Traits::StorageTag>));
|
(vtkm::cont::ArrayHandle<typename Traits::ValueType, typename Traits::StorageTag>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
template <typename RealStorageTag>
|
template <typename RealStorageTag>
|
||||||
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<ValueType, RealStorageTag>& src)
|
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<ValueType, RealStorageTag>& src)
|
||||||
: Superclass(StorageType::CreateBuffers(src))
|
: Superclass(StorageType::CreateBuffers(src))
|
||||||
|
@ -248,10 +248,6 @@ public:
|
|||||||
vtkm::cont::StorageTagPermutation<typename IndexArrayHandleType::StorageTag,
|
vtkm::cont::StorageTagPermutation<typename IndexArrayHandleType::StorageTag,
|
||||||
typename ValueArrayHandleType::StorageTag>>));
|
typename ValueArrayHandleType::StorageTag>>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandlePermutation(const IndexArrayHandleType& indexArray,
|
ArrayHandlePermutation(const IndexArrayHandleType& indexArray,
|
||||||
const ValueArrayHandleType& valueArray)
|
const ValueArrayHandleType& valueArray)
|
||||||
|
@ -604,10 +604,6 @@ public:
|
|||||||
(vtkm::cont::ArrayHandle<internal::detail::RecombinedValueType<ComponentType>,
|
(vtkm::cont::ArrayHandle<internal::detail::RecombinedValueType<ComponentType>,
|
||||||
vtkm::cont::internal::StorageTagRecombineVec>));
|
vtkm::cont::internal::StorageTagRecombineVec>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
vtkm::IdComponent GetNumberOfComponents() const
|
vtkm::IdComponent GetNumberOfComponents() const
|
||||||
{
|
{
|
||||||
return StorageType::GetNumberOfComponents(this->GetBuffers());
|
return StorageType::GetNumberOfComponents(this->GetBuffers());
|
||||||
|
@ -156,7 +156,6 @@ public:
|
|||||||
(vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
|
(vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
|
||||||
StorageTagReverse<typename ArrayHandleType::StorageTag>>));
|
StorageTagReverse<typename ArrayHandleType::StorageTag>>));
|
||||||
|
|
||||||
public:
|
|
||||||
ArrayHandleReverse(const ArrayHandleType& handle)
|
ArrayHandleReverse(const ArrayHandleType& handle)
|
||||||
: Superclass(handle.GetBuffers())
|
: Superclass(handle.GetBuffers())
|
||||||
{
|
{
|
||||||
|
@ -327,7 +327,6 @@ public:
|
|||||||
vtkm::cont::StorageTagRuntimeVec>));
|
vtkm::cont::StorageTagRuntimeVec>));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
using ComponentsArrayType = vtkm::cont::ArrayHandle<ComponentType, StorageTagBasic>;
|
using ComponentsArrayType = vtkm::cont::ArrayHandle<ComponentType, StorageTagBasic>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -246,8 +246,6 @@ class ArrayHandleSOA : public ArrayHandle<T, vtkm::cont::StorageTagSOA>
|
|||||||
using ComponentType = typename vtkm::VecTraits<T>::ComponentType;
|
using ComponentType = typename vtkm::VecTraits<T>::ComponentType;
|
||||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<T>::NUM_COMPONENTS;
|
static constexpr vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<T>::NUM_COMPONENTS;
|
||||||
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagSOA>;
|
|
||||||
|
|
||||||
using ComponentArrayType = vtkm::cont::ArrayHandle<ComponentType, vtkm::cont::StorageTagBasic>;
|
using ComponentArrayType = vtkm::cont::ArrayHandle<ComponentType, vtkm::cont::StorageTagBasic>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -333,10 +333,6 @@ public:
|
|||||||
(ArrayHandleStride<T>),
|
(ArrayHandleStride<T>),
|
||||||
(ArrayHandle<T, vtkm::cont::StorageTagStride>));
|
(ArrayHandle<T, vtkm::cont::StorageTagStride>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ArrayHandleStride(vtkm::Id stride, vtkm::Id offset, vtkm::Id modulo = 0, vtkm::Id divisor = 1)
|
ArrayHandleStride(vtkm::Id stride, vtkm::Id offset, vtkm::Id modulo = 0, vtkm::Id divisor = 1)
|
||||||
: Superclass(StorageType::CreateBuffers(
|
: Superclass(StorageType::CreateBuffers(
|
||||||
vtkm::cont::internal::Buffer{},
|
vtkm::cont::internal::Buffer{},
|
||||||
|
@ -246,8 +246,7 @@ class Storage<typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueT
|
|||||||
using FunctorManager = TransformFunctorManager<FunctorType>;
|
using FunctorManager = TransformFunctorManager<FunctorType>;
|
||||||
using ValueType = typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueType;
|
using ValueType = typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueType;
|
||||||
|
|
||||||
using SourceStorage =
|
using SourceStorage = typename ArrayHandleType::StorageType;
|
||||||
Storage<typename ArrayHandleType::ValueType, typename ArrayHandleType::StorageTag>;
|
|
||||||
|
|
||||||
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
|
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
|
||||||
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
||||||
@ -323,8 +322,7 @@ class Storage<
|
|||||||
using InverseFunctorManager = TransformFunctorManager<InverseFunctorType>;
|
using InverseFunctorManager = TransformFunctorManager<InverseFunctorType>;
|
||||||
using ValueType = typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueType;
|
using ValueType = typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueType;
|
||||||
|
|
||||||
using SourceStorage =
|
using SourceStorage = typename ArrayHandleType::StorageType;
|
||||||
Storage<typename ArrayHandleType::ValueType, typename ArrayHandleType::StorageTag>;
|
|
||||||
|
|
||||||
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
|
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
|
||||||
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
||||||
@ -454,10 +452,6 @@ public:
|
|||||||
typename internal::StorageTagTransform<ArrayHandleType, FunctorType>::ValueType,
|
typename internal::StorageTagTransform<ArrayHandleType, FunctorType>::ValueType,
|
||||||
internal::StorageTagTransform<ArrayHandleType, FunctorType>>));
|
internal::StorageTagTransform<ArrayHandleType, FunctorType>>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleTransform(const ArrayHandleType& handle,
|
ArrayHandleTransform(const ArrayHandleType& handle,
|
||||||
const FunctorType& functor = FunctorType{},
|
const FunctorType& functor = FunctorType{},
|
||||||
@ -498,10 +492,6 @@ public:
|
|||||||
ValueType,
|
ValueType,
|
||||||
internal::StorageTagTransform<ArrayHandleType, FunctorType, InverseFunctorType>>));
|
internal::StorageTagTransform<ArrayHandleType, FunctorType, InverseFunctorType>>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ArrayHandleTransform(const ArrayHandleType& handle,
|
ArrayHandleTransform(const ArrayHandleType& handle,
|
||||||
const FunctorType& functor = FunctorType(),
|
const FunctorType& functor = FunctorType(),
|
||||||
const InverseFunctorType& inverseFunctor = InverseFunctorType())
|
const InverseFunctorType& inverseFunctor = InverseFunctorType())
|
||||||
|
@ -51,10 +51,6 @@ public:
|
|||||||
ArrayHandleUniformPointCoordinates,
|
ArrayHandleUniformPointCoordinates,
|
||||||
(vtkm::cont::ArrayHandle<vtkm::Vec3f, vtkm::cont::StorageTagUniformPoints>));
|
(vtkm::cont::ArrayHandle<vtkm::Vec3f, vtkm::cont::StorageTagUniformPoints>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleUniformPointCoordinates(vtkm::Id3 dimensions,
|
ArrayHandleUniformPointCoordinates(vtkm::Id3 dimensions,
|
||||||
ValueType origin = ValueType(0.0f, 0.0f, 0.0f),
|
ValueType origin = ValueType(0.0f, 0.0f, 0.0f),
|
||||||
|
@ -197,10 +197,6 @@ public:
|
|||||||
(vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
|
(vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
|
||||||
StorageTagView<typename ArrayHandleType::StorageTag>>));
|
StorageTagView<typename ArrayHandleType::StorageTag>>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleView(const ArrayHandleType& array, vtkm::Id startIndex, vtkm::Id numValues)
|
ArrayHandleView(const ArrayHandleType& array, vtkm::Id startIndex, vtkm::Id numValues)
|
||||||
: Superclass(StorageType::CreateBuffers(startIndex, numValues, array))
|
: Superclass(StorageType::CreateBuffers(startIndex, numValues, array))
|
||||||
|
@ -291,10 +291,6 @@ public:
|
|||||||
(ArrayHandleXGCCoordinates<T>),
|
(ArrayHandleXGCCoordinates<T>),
|
||||||
(vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagXGCCoordinates>));
|
(vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, vtkm::cont::StorageTagXGCCoordinates>));
|
||||||
|
|
||||||
private:
|
|
||||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
ArrayHandleXGCCoordinates(const OriginalType& array,
|
ArrayHandleXGCCoordinates(const OriginalType& array,
|
||||||
vtkm::Id numberOfPlanes,
|
vtkm::Id numberOfPlanes,
|
||||||
|
@ -129,10 +129,6 @@ struct ArrayHandleZipTraits
|
|||||||
using Tag =
|
using Tag =
|
||||||
StorageTagZip<typename FirstHandleType::StorageTag, typename SecondHandleType::StorageTag>;
|
StorageTagZip<typename FirstHandleType::StorageTag, typename SecondHandleType::StorageTag>;
|
||||||
|
|
||||||
/// The storage type.
|
|
||||||
///
|
|
||||||
using Storage = vtkm::cont::internal::Storage<ValueType, Tag>;
|
|
||||||
|
|
||||||
/// The superclass for ArrayHandleZip.
|
/// The superclass for ArrayHandleZip.
|
||||||
///
|
///
|
||||||
using Superclass = vtkm::cont::ArrayHandle<ValueType, Tag>;
|
using Superclass = vtkm::cont::ArrayHandle<ValueType, Tag>;
|
||||||
@ -259,9 +255,6 @@ class ArrayHandleZip
|
|||||||
// template argument is not a valid ArrayHandle type.
|
// template argument is not a valid ArrayHandle type.
|
||||||
VTKM_IS_ARRAY_HANDLE(SecondHandleType);
|
VTKM_IS_ARRAY_HANDLE(SecondHandleType);
|
||||||
|
|
||||||
using StorageType =
|
|
||||||
typename internal::ArrayHandleZipTraits<FirstHandleType, SecondHandleType>::Storage;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VTKM_ARRAY_HANDLE_SUBCLASS(
|
VTKM_ARRAY_HANDLE_SUBCLASS(
|
||||||
ArrayHandleZip,
|
ArrayHandleZip,
|
||||||
|
@ -27,12 +27,7 @@ template <typename ValueType>
|
|||||||
struct TemplatedTests
|
struct TemplatedTests
|
||||||
{
|
{
|
||||||
using ArrayHandleType = vtkm::cont::ArrayHandleCounting<ValueType>;
|
using ArrayHandleType = vtkm::cont::ArrayHandleCounting<ValueType>;
|
||||||
|
using PortalType = typename ArrayHandleType::ReadPortalType;
|
||||||
using ArrayHandleType2 = vtkm::cont::ArrayHandle<ValueType, vtkm::cont::StorageTagCounting>;
|
|
||||||
|
|
||||||
using PortalType =
|
|
||||||
typename vtkm::cont::internal::Storage<ValueType,
|
|
||||||
typename ArrayHandleType::StorageTag>::ReadPortalType;
|
|
||||||
|
|
||||||
void operator()(const ValueType& startingValue, const ValueType& step)
|
void operator()(const ValueType& startingValue, const ValueType& step)
|
||||||
{
|
{
|
||||||
@ -41,7 +36,8 @@ struct TemplatedTests
|
|||||||
ArrayHandleType arrayMake =
|
ArrayHandleType arrayMake =
|
||||||
vtkm::cont::make_ArrayHandleCounting(startingValue, step, ARRAY_SIZE);
|
vtkm::cont::make_ArrayHandleCounting(startingValue, step, ARRAY_SIZE);
|
||||||
|
|
||||||
ArrayHandleType2 arrayHandle = ArrayHandleType(startingValue, step, ARRAY_SIZE);
|
typename ArrayHandleType::Superclass arrayHandle =
|
||||||
|
ArrayHandleType(startingValue, step, ARRAY_SIZE);
|
||||||
|
|
||||||
VTKM_TEST_ASSERT(arrayConst.GetNumberOfValues() == ARRAY_SIZE,
|
VTKM_TEST_ASSERT(arrayConst.GetNumberOfValues() == ARRAY_SIZE,
|
||||||
"Counting array using constructor has wrong size.");
|
"Counting array using constructor has wrong size.");
|
||||||
|
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
|
set(contour_headers
|
||||||
|
AbstractContour.h
|
||||||
ClipWithField.h
|
ClipWithField.h
|
||||||
ClipWithImplicitFunction.h
|
ClipWithImplicitFunction.h
|
||||||
Contour.h
|
Contour.h
|
||||||
|
ContourFlyingEdges.h
|
||||||
|
ContourMarchingCells.h
|
||||||
MIRFilter.h
|
MIRFilter.h
|
||||||
Slice.h
|
Slice.h
|
||||||
)
|
)
|
||||||
@ -19,15 +22,23 @@ set(contour_headers
|
|||||||
set(contour_sources_device
|
set(contour_sources_device
|
||||||
ClipWithField.cxx
|
ClipWithField.cxx
|
||||||
ClipWithImplicitFunction.cxx
|
ClipWithImplicitFunction.cxx
|
||||||
Contour.cxx
|
ContourFlyingEdges.cxx
|
||||||
|
ContourMarchingCells.cxx
|
||||||
MIRFilter.cxx
|
MIRFilter.cxx
|
||||||
Slice.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)
|
set_source_files_properties(Contour.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
|
||||||
|
|
||||||
vtkm_library(
|
vtkm_library(
|
||||||
NAME vtkm_filter_contour
|
NAME vtkm_filter_contour
|
||||||
|
SOURCES ${contour_sources}
|
||||||
HEADERS ${contour_headers}
|
HEADERS ${contour_headers}
|
||||||
DEVICE_SOURCES ${contour_sources_device}
|
DEVICE_SOURCES ${contour_sources_device}
|
||||||
USE_VTKM_JOB_POOL
|
USE_VTKM_JOB_POOL
|
||||||
|
@ -7,16 +7,13 @@
|
|||||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
// PURPOSE. See the above copyright notice for more information.
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
|
||||||
#include <vtkm/cont/CellSetSingleType.h>
|
#include <vtkm/cont/CellSetSingleType.h>
|
||||||
#include <vtkm/cont/CellSetStructured.h>
|
#include <vtkm/cont/CellSetStructured.h>
|
||||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
|
||||||
#include <vtkm/cont/UnknownCellSet.h>
|
#include <vtkm/cont/UnknownCellSet.h>
|
||||||
|
|
||||||
#include <vtkm/filter/MapFieldPermutation.h>
|
|
||||||
#include <vtkm/filter/contour/Contour.h>
|
#include <vtkm/filter/contour/Contour.h>
|
||||||
#include <vtkm/filter/contour/worklet/Contour.h>
|
#include <vtkm/filter/contour/ContourFlyingEdges.h>
|
||||||
#include <vtkm/filter/vector_analysis/SurfaceNormals.h>
|
#include <vtkm/filter/contour/ContourMarchingCells.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
@ -25,155 +22,48 @@ namespace filter
|
|||||||
|
|
||||||
using SupportedTypes = vtkm::List<vtkm::UInt8, vtkm::Int8, vtkm::Float32, vtkm::Float64>;
|
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
|
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::cont::DataSet Contour::DoExecute(const vtkm::cont::DataSet& inDataSet)
|
||||||
{
|
{
|
||||||
vtkm::worklet::Contour worklet;
|
// Switch between Marching Cubes and Flying Edges implementation of contour,
|
||||||
worklet.SetMergeDuplicatePoints(this->GetMergeDuplicatePoints());
|
// 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;
|
||||||
|
|
||||||
|
// For now, Flying Edges is only used for 3D Structured CellSets,
|
||||||
|
// using Uniform coordinates.
|
||||||
|
if (inCellSet.template IsType<vtkm::cont::CellSetStructured<3>>() &&
|
||||||
|
inCoords.template IsType<
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f, vtkm::cont::StorageTagUniformPoints>>())
|
||||||
{
|
{
|
||||||
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
|
return implementation->Execute(inDataSet);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
} // namespace contour
|
} // namespace contour
|
||||||
} // namespace filter
|
} // namespace filter
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifndef vtk_m_filter_contour_Contour_h
|
#ifndef vtk_m_filter_contour_Contour_h
|
||||||
#define 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>
|
#include <vtkm/filter/contour/vtkm_filter_contour_export.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -25,103 +25,33 @@ namespace contour
|
|||||||
/// Takes as input a volume (e.g., 3D structured point set) and generates on
|
/// Takes as input a volume (e.g., 3D structured point set) and generates on
|
||||||
/// output one or more isosurfaces.
|
/// output one or more isosurfaces.
|
||||||
/// Multiple contour values must be specified to generate the 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
|
/// @warning
|
||||||
/// This filter is currently only supports 3D volumes.
|
/// 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:
|
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
|
/// Set/Get whether the fast path should be used for normals computation for
|
||||||
/// structured datasets. Off by default.
|
/// structured datasets. Off by default.
|
||||||
VTKM_CONT
|
VTKM_DEPRECATED(2.1, "Use SetComputeFastNormals.")
|
||||||
void SetComputeFastNormalsForStructured(bool on) { this->ComputeFastNormalsForStructured = on; }
|
VTKM_CONT void SetComputeFastNormalsForStructured(bool on) { this->SetComputeFastNormals(on); }
|
||||||
VTKM_CONT
|
VTKM_DEPRECATED(2.1, "Use GetComputeFastNormals.")
|
||||||
bool GetComputeFastNormalsForStructured() const { return this->ComputeFastNormalsForStructured; }
|
VTKM_CONT bool GetComputeFastNormalsForStructured() const
|
||||||
|
{
|
||||||
|
return this->GetComputeFastNormals();
|
||||||
|
}
|
||||||
|
|
||||||
/// Set/Get whether the fast path should be used for normals computation for
|
/// Set/Get whether the fast path should be used for normals computation for
|
||||||
/// unstructured datasets. On by default.
|
/// unstructured datasets. On by default.
|
||||||
VTKM_CONT
|
VTKM_DEPRECATED(2.1, "Use SetComputeFastNormals.")
|
||||||
void SetComputeFastNormalsForUnstructured(bool on)
|
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:
|
protected:
|
||||||
// Needed by the subclass Slice
|
// Needed by the subclass Slice
|
||||||
|
112
vtkm/filter/contour/ContourFlyingEdges.cxx
Normal file
112
vtkm/filter/contour/ContourFlyingEdges.cxx
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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>>() ||
|
||||||
|
!inCoords.GetData()
|
||||||
|
.template IsType<
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Vec3f, vtkm::cont::StorageTagUniformPoints>>())
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorFilterExecution("This filter is only available for 3-Dimensional "
|
||||||
|
"Structured Cell Sets using uniform point coordinates.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.GetData().AsArrayHandle<vtkm::cont::ArrayHandleUniformPointCoordinates>(),
|
||||||
|
concrete,
|
||||||
|
vertices,
|
||||||
|
normals);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outputCells = worklet.Run(
|
||||||
|
ivalues,
|
||||||
|
inputCells,
|
||||||
|
inCoords.GetData().AsArrayHandle<vtkm::cont::ArrayHandleUniformPointCoordinates>(),
|
||||||
|
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/Math.h>
|
||||||
#include <vtkm/cont/Algorithm.h>
|
#include <vtkm/cont/Algorithm.h>
|
||||||
#include <vtkm/cont/DataSet.h>
|
#include <vtkm/cont/DataSet.h>
|
||||||
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||||
#include <vtkm/cont/testing/Testing.h>
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
|
||||||
#include <vtkm/filter/contour/Contour.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/filter/field_transform/GenerateIds.h>
|
||||||
|
|
||||||
#include <vtkm/io/VTKDataSetReader.h>
|
#include <vtkm/io/VTKDataSetReader.h>
|
||||||
@ -26,7 +29,8 @@ namespace
|
|||||||
class TestContourFilter
|
class TestContourFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void TestContourUniformGrid() const
|
template <typename ContourFilterType>
|
||||||
|
void TestContourUniformGrid(vtkm::IdComponent numPointsNoMergeDuplicate) const
|
||||||
{
|
{
|
||||||
std::cout << "Testing Contour filter on a uniform grid" << std::endl;
|
std::cout << "Testing Contour filter on a uniform grid" << std::endl;
|
||||||
|
|
||||||
@ -38,14 +42,14 @@ public:
|
|||||||
genIds.SetCellFieldName("cellvar");
|
genIds.SetCellFieldName("cellvar");
|
||||||
vtkm::cont::DataSet dataSet = genIds.Execute(tangle.Execute());
|
vtkm::cont::DataSet dataSet = genIds.Execute(tangle.Execute());
|
||||||
|
|
||||||
vtkm::filter::contour::Contour mc;
|
ContourFilterType filter;
|
||||||
|
|
||||||
mc.SetGenerateNormals(true);
|
filter.SetGenerateNormals(true);
|
||||||
mc.SetIsoValue(0, 0.5);
|
filter.SetIsoValue(0, 0.5);
|
||||||
mc.SetActiveField("tangle");
|
filter.SetActiveField("tangle");
|
||||||
mc.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::None);
|
filter.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::None);
|
||||||
|
|
||||||
auto result = mc.Execute(dataSet);
|
auto result = filter.Execute(dataSet);
|
||||||
{
|
{
|
||||||
VTKM_TEST_ASSERT(result.GetNumberOfCoordinateSystems() == 1,
|
VTKM_TEST_ASSERT(result.GetNumberOfCoordinateSystems() == 1,
|
||||||
"Wrong number of coordinate systems in the output dataset");
|
"Wrong number of coordinate systems in the output dataset");
|
||||||
@ -55,8 +59,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// let's execute with mapping fields.
|
// let's execute with mapping fields.
|
||||||
mc.SetFieldsToPass({ "tangle", "cellvar" });
|
filter.SetFieldsToPass({ "tangle", "cellvar" });
|
||||||
result = mc.Execute(dataSet);
|
result = filter.Execute(dataSet);
|
||||||
{
|
{
|
||||||
const bool isMapped = result.HasField("tangle");
|
const bool isMapped = result.HasField("tangle");
|
||||||
VTKM_TEST_ASSERT(isMapped, "mapping should pass");
|
VTKM_TEST_ASSERT(isMapped, "mapping should pass");
|
||||||
@ -99,16 +103,13 @@ public:
|
|||||||
VTKM_TEST_ASSERT(cells.GetNumberOfCells() == 160, "");
|
VTKM_TEST_ASSERT(cells.GetNumberOfCells() == 160, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Now try with vertex merging disabled. Since this
|
//Now try with vertex merging disabled.
|
||||||
//we use FlyingEdges we now which does point merging for free
|
filter.SetMergeDuplicatePoints(false);
|
||||||
//so we should see the number of points not change
|
filter.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::All);
|
||||||
mc.SetMergeDuplicatePoints(false);
|
result = filter.Execute(dataSet);
|
||||||
mc.SetFieldsToPass(vtkm::filter::FieldSelection::Mode::All);
|
|
||||||
result = mc.Execute(dataSet);
|
|
||||||
{
|
{
|
||||||
vtkm::cont::CoordinateSystem coords = result.GetCoordinateSystem();
|
vtkm::cont::CoordinateSystem coords = result.GetCoordinateSystem();
|
||||||
|
VTKM_TEST_ASSERT(coords.GetNumberOfPoints() == numPointsNoMergeDuplicate,
|
||||||
VTKM_TEST_ASSERT(coords.GetNumberOfPoints() == 72,
|
|
||||||
"Shouldn't have less coordinates than the unmerged version");
|
"Shouldn't have less coordinates than the unmerged version");
|
||||||
|
|
||||||
//verify that the number of cells is correct (160)
|
//verify that the number of cells is correct (160)
|
||||||
@ -120,20 +121,24 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ContourFilterType>
|
||||||
void Test3DUniformDataSet0() const
|
void Test3DUniformDataSet0() const
|
||||||
{
|
{
|
||||||
vtkm::cont::testing::MakeTestDataSet maker;
|
vtkm::cont::testing::MakeTestDataSet maker;
|
||||||
vtkm::cont::DataSet inputData = maker.Make3DUniformDataSet0();
|
vtkm::cont::DataSet inputData = maker.Make3DUniformDataSet0();
|
||||||
std::string fieldName = "pointvar";
|
std::string fieldName = "pointvar";
|
||||||
|
|
||||||
// Defend the test against changes to Make3DUniformDataSet0():
|
// Defend the test against changes to Make3DUniformDataSet0():
|
||||||
VTKM_TEST_ASSERT(inputData.HasField(fieldName));
|
VTKM_TEST_ASSERT(inputData.HasField(fieldName));
|
||||||
vtkm::cont::Field pointField = inputData.GetField(fieldName);
|
vtkm::cont::Field pointField = inputData.GetField(fieldName);
|
||||||
|
|
||||||
vtkm::Range range;
|
vtkm::Range range;
|
||||||
pointField.GetRange(&range);
|
pointField.GetRange(&range);
|
||||||
vtkm::FloatDefault isovalue = 100.0;
|
vtkm::FloatDefault isovalue = 100.0;
|
||||||
// Range = [10.1, 180.5]
|
// Range = [10.1, 180.5]
|
||||||
VTKM_TEST_ASSERT(range.Contains(isovalue));
|
VTKM_TEST_ASSERT(range.Contains(isovalue));
|
||||||
vtkm::filter::contour::Contour filter;
|
|
||||||
|
ContourFilterType filter;
|
||||||
filter.SetGenerateNormals(false);
|
filter.SetGenerateNormals(false);
|
||||||
filter.SetMergeDuplicatePoints(true);
|
filter.SetMergeDuplicatePoints(true);
|
||||||
filter.SetIsoValue(isovalue);
|
filter.SetIsoValue(isovalue);
|
||||||
@ -143,6 +148,7 @@ public:
|
|||||||
VTKM_TEST_ASSERT(outputData.GetNumberOfPoints() == 9);
|
VTKM_TEST_ASSERT(outputData.GetNumberOfPoints() == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ContourFilterType>
|
||||||
void TestContourWedges() const
|
void TestContourWedges() const
|
||||||
{
|
{
|
||||||
std::cout << "Testing Contour filter on wedge cells" << std::endl;
|
std::cout << "Testing Contour filter on wedge cells" << std::endl;
|
||||||
@ -158,7 +164,7 @@ public:
|
|||||||
vtkm::cont::ArrayHandle<vtkm::Float32> fieldArray;
|
vtkm::cont::ArrayHandle<vtkm::Float32> fieldArray;
|
||||||
dataSet.GetPointField("gyroid").GetData().AsArrayHandle(fieldArray);
|
dataSet.GetPointField("gyroid").GetData().AsArrayHandle(fieldArray);
|
||||||
|
|
||||||
vtkm::filter::contour::Contour isosurfaceFilter;
|
ContourFilterType isosurfaceFilter;
|
||||||
isosurfaceFilter.SetActiveField("gyroid");
|
isosurfaceFilter.SetActiveField("gyroid");
|
||||||
isosurfaceFilter.SetMergeDuplicatePoints(false);
|
isosurfaceFilter.SetMergeDuplicatePoints(false);
|
||||||
isosurfaceFilter.SetIsoValue(0.0);
|
isosurfaceFilter.SetIsoValue(0.0);
|
||||||
@ -167,11 +173,54 @@ public:
|
|||||||
VTKM_TEST_ASSERT(result.GetNumberOfCells() == 52);
|
VTKM_TEST_ASSERT(result.GetNumberOfCells() == 52);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestUnsupportedFlyingEdges() const
|
||||||
|
{
|
||||||
|
vtkm::cont::testing::MakeTestDataSet maker;
|
||||||
|
|
||||||
|
vtkm::cont::DataSet rectilinearDataset = maker.Make3DRectilinearDataSet0();
|
||||||
|
vtkm::cont::DataSet explicitDataSet = maker.Make3DExplicitDataSet0();
|
||||||
|
|
||||||
|
vtkm::filter::contour::ContourFlyingEdges filter;
|
||||||
|
filter.SetIsoValue(2.0);
|
||||||
|
filter.SetActiveField("pointvar");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
filter.Execute(rectilinearDataset);
|
||||||
|
VTKM_TEST_FAIL("Flying Edges filter should not run on datasets with rectilinear coordinates");
|
||||||
|
}
|
||||||
|
catch (vtkm::cont::ErrorFilterExecution&)
|
||||||
|
{
|
||||||
|
std::cout << "Execution successfully aborted" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void operator()() const
|
void operator()() const
|
||||||
{
|
{
|
||||||
this->Test3DUniformDataSet0();
|
this->TestContourUniformGrid<vtkm::filter::contour::Contour>(72);
|
||||||
this->TestContourUniformGrid();
|
this->TestContourUniformGrid<vtkm::filter::contour::ContourFlyingEdges>(72);
|
||||||
this->TestContourWedges();
|
// 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->TestUnsupportedFlyingEdges();
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // class TestContourFilter
|
}; // class TestContourFilter
|
||||||
|
@ -105,6 +105,14 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
|||||||
vtkm::filter::contour::Contour mc;
|
vtkm::filter::contour::Contour mc;
|
||||||
mc.SetIsoValue(0, 200);
|
mc.SetIsoValue(0, 200);
|
||||||
mc.SetGenerateNormals(true);
|
mc.SetGenerateNormals(true);
|
||||||
|
if (structured)
|
||||||
|
{
|
||||||
|
mc.SetComputeFastNormals(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mc.SetComputeFastNormals(true);
|
||||||
|
}
|
||||||
|
|
||||||
// Test default normals generation: high quality for structured, fast for unstructured.
|
// Test default normals generation: high quality for structured, fast for unstructured.
|
||||||
auto expected = structured ? hq_sg : fast;
|
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
|
// Test the other normals generation method
|
||||||
if (structured)
|
if (structured)
|
||||||
{
|
{
|
||||||
mc.SetComputeFastNormalsForStructured(true);
|
mc.SetComputeFastNormals(true);
|
||||||
expected = fast;
|
expected = fast;
|
||||||
if (using_fe_y_alg_ordering)
|
if (using_fe_y_alg_ordering)
|
||||||
{
|
{
|
||||||
@ -145,7 +153,7 @@ void TestNormals(const vtkm::cont::DataSet& dataset, bool structured)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mc.SetComputeFastNormalsForUnstructured(false);
|
mc.SetComputeFastNormals(false);
|
||||||
expected = hq_ug;
|
expected = hq_ug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
set(headers
|
set(headers
|
||||||
Clip.h
|
Clip.h
|
||||||
Contour.h
|
ContourFlyingEdges.h
|
||||||
|
ContourMarchingCells.h
|
||||||
MIR.h
|
MIR.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
114
vtkm/filter/contour/worklet/ContourFlyingEdges.h
Normal file
114
vtkm/filter/contour/worklet/ContourFlyingEdges.h
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 StorageTagField,
|
||||||
|
typename CoordinateType,
|
||||||
|
typename StorageTagVertices>
|
||||||
|
vtkm::cont::CellSetSingleType<> Run(
|
||||||
|
const std::vector<ValueType>& isovalues,
|
||||||
|
const vtkm::cont::CellSetStructured<3>& cells,
|
||||||
|
const vtkm::cont::ArrayHandleUniformPointCoordinates& 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 StorageTagField,
|
||||||
|
typename CoordinateType,
|
||||||
|
typename StorageTagVertices,
|
||||||
|
typename StorageTagNormals>
|
||||||
|
vtkm::cont::CellSetSingleType<> Run(
|
||||||
|
const std::vector<ValueType>& isovalues,
|
||||||
|
const vtkm::cont::CellSetStructured<3>& cells,
|
||||||
|
const vtkm::cont::ArrayHandleUniformPointCoordinates& 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.
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef vtk_m_worklet_Contour_h
|
#ifndef vtk_m_worklet_ContourMarchingCells_h
|
||||||
#define vtk_m_worklet_Contour_h
|
#define vtk_m_worklet_ContourMarchingCells_h
|
||||||
|
|
||||||
#include <vtkm/cont/ArrayCopy.h>
|
|
||||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
|
||||||
|
|
||||||
#include <vtkm/filter/contour/worklet/contour/CommonState.h>
|
#include <vtkm/filter/contour/worklet/contour/CommonState.h>
|
||||||
#include <vtkm/filter/contour/worklet/contour/FieldPropagation.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>
|
#include <vtkm/filter/contour/worklet/contour/MarchingCells.h>
|
||||||
|
|
||||||
|
|
||||||
@ -25,8 +20,6 @@ namespace vtkm
|
|||||||
{
|
{
|
||||||
namespace worklet
|
namespace worklet
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
namespace contour
|
namespace contour
|
||||||
{
|
{
|
||||||
struct DeduceCoordType
|
struct DeduceCoordType
|
||||||
@ -39,16 +32,6 @@ struct DeduceCoordType
|
|||||||
{
|
{
|
||||||
result = marching_cells::execute(cells, coords, std::forward<Args>(args)...);
|
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
|
struct DeduceCellType
|
||||||
@ -62,13 +45,12 @@ struct DeduceCellType
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Compute the isosurface of a given 3D data set, supports all
|
/// \brief Compute the isosurface of a given 3D data set, supports all linear cell types
|
||||||
/// linear cell types
|
class ContourMarchingCells
|
||||||
class Contour
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Contour(bool mergeDuplicates = true)
|
ContourMarchingCells(bool mergeDuplicates = true)
|
||||||
: SharedState(mergeDuplicates)
|
: SharedState(mergeDuplicates)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -89,6 +71,23 @@ public:
|
|||||||
vtkm::cont::ArrayHandle<vtkm::Id> GetCellIdMap() const { return this->SharedState.CellIdMap; }
|
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,
|
template <typename ValueType,
|
||||||
typename CellSetType,
|
typename CellSetType,
|
||||||
typename CoordinateSystem,
|
typename CoordinateSystem,
|
||||||
@ -118,7 +117,7 @@ public:
|
|||||||
return outputCells;
|
return outputCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
// Filter called with normals generation
|
||||||
template <typename ValueType,
|
template <typename ValueType,
|
||||||
typename CellSetType,
|
typename CellSetType,
|
||||||
typename CoordinateSystem,
|
typename CoordinateSystem,
|
||||||
@ -149,22 +148,6 @@ public:
|
|||||||
return outputCells;
|
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:
|
private:
|
||||||
vtkm::worklet::contour::CommonState SharedState;
|
vtkm::worklet::contour::CommonState SharedState;
|
||||||
@ -172,4 +155,4 @@ private:
|
|||||||
}
|
}
|
||||||
} // namespace vtkm::worklet
|
} // namespace vtkm::worklet
|
||||||
|
|
||||||
#endif // vtk_m_worklet_Contour_h
|
#endif // vtk_m_worklet_ContourMarchingCells_h
|
@ -137,8 +137,8 @@ protected:
|
|||||||
if (!this->UseAsynchronousCommunication)
|
if (!this->UseAsynchronousCommunication)
|
||||||
{
|
{
|
||||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||||
"Synchronous communication not supported for AdvectAlgorithmThreaded. Forcing "
|
"Synchronous communication not supported for AdvectAlgorithmThreaded."
|
||||||
"asynchronous communication.");
|
"Forcing asynchronous communication.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useAsync = true;
|
bool useAsync = true;
|
||||||
|
@ -61,6 +61,15 @@ public:
|
|||||||
this->Init(pds.GetPartitions(), blockIds);
|
this->Init(pds.GetPartitions(), blockIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vtkm::Bounds GetGlobalBounds() const { return this->GlobalBounds; }
|
||||||
|
|
||||||
|
vtkm::Bounds GetBlockBounds(vtkm::Id idx) const
|
||||||
|
{
|
||||||
|
VTKM_ASSERT(idx >= 0 && static_cast<std::size_t>(idx) < this->BlockBounds.size());
|
||||||
|
|
||||||
|
return this->BlockBounds[static_cast<std::size_t>(idx)];
|
||||||
|
}
|
||||||
|
|
||||||
vtkm::Id GetLocalBlockId(vtkm::Id idx) const
|
vtkm::Id GetLocalBlockId(vtkm::Id idx) const
|
||||||
{
|
{
|
||||||
VTKM_ASSERT(idx >= 0 && idx < this->LocalNumBlocks);
|
VTKM_ASSERT(idx >= 0 && idx < this->LocalNumBlocks);
|
||||||
@ -138,7 +147,7 @@ private:
|
|||||||
|
|
||||||
//note: there might be duplicates...
|
//note: there might be duplicates...
|
||||||
vtkm::Id globalNumBlocks =
|
vtkm::Id globalNumBlocks =
|
||||||
std::accumulate(globalBlockCounts.begin(), globalBlockCounts.end(), 0);
|
std::accumulate(globalBlockCounts.begin(), globalBlockCounts.end(), vtkm::Id{ 0 });
|
||||||
|
|
||||||
//3. given the counts per rank, calc offset for this rank.
|
//3. given the counts per rank, calc offset for this rank.
|
||||||
vtkm::Id offset = 0;
|
vtkm::Id offset = 0;
|
||||||
|
@ -74,15 +74,16 @@ public:
|
|||||||
|
|
||||||
void Validate(vtkm::Id num)
|
void Validate(vtkm::Id num)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
|
||||||
//Make sure we didn't miss anything. Every particle goes into a single bucket.
|
//Make sure we didn't miss anything. Every particle goes into a single bucket.
|
||||||
VTKM_ASSERT(static_cast<std::size_t>(num) ==
|
if ((static_cast<std::size_t>(num) !=
|
||||||
(this->InBounds.Particles.size() + this->OutOfBounds.Particles.size() +
|
(this->InBounds.Particles.size() + this->OutOfBounds.Particles.size() +
|
||||||
this->TermIdx.size()));
|
this->TermIdx.size())) ||
|
||||||
VTKM_ASSERT(this->InBounds.Particles.size() == this->InBounds.BlockIDs.size());
|
(this->InBounds.Particles.size() != this->InBounds.BlockIDs.size()) ||
|
||||||
VTKM_ASSERT(this->OutOfBounds.Particles.size() == this->OutOfBounds.BlockIDs.size());
|
(this->OutOfBounds.Particles.size() != this->OutOfBounds.BlockIDs.size()) ||
|
||||||
VTKM_ASSERT(this->TermIdx.size() == this->TermID.size());
|
(this->TermIdx.size() != this->TermID.size()))
|
||||||
#endif
|
{
|
||||||
|
throw vtkm::cont::ErrorFilterExecution("Particle count mismatch after classification");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTerminated(vtkm::Id idx, vtkm::Id pID)
|
void AddTerminated(vtkm::Id idx, vtkm::Id pID)
|
||||||
|
@ -115,10 +115,10 @@ void SetFilter(FilterType& filter,
|
|||||||
filter.SetSeeds(seedArray);
|
filter.SetSeeds(seedArray);
|
||||||
filter.SetActiveField(fieldName);
|
filter.SetActiveField(fieldName);
|
||||||
filter.SetUseThreadedAlgorithm(useThreaded);
|
filter.SetUseThreadedAlgorithm(useThreaded);
|
||||||
// if (useAsyncComm)
|
if (useAsyncComm)
|
||||||
// filter.SetUseAsynchronousCommunication();
|
filter.SetUseAsynchronousCommunication();
|
||||||
// else
|
else
|
||||||
// filter.SetUseSynchronousCommunication();
|
filter.SetUseSynchronousCommunication();
|
||||||
|
|
||||||
if (useBlockIds)
|
if (useBlockIds)
|
||||||
filter.SetBlockIDs(blockIds);
|
filter.SetBlockIDs(blockIds);
|
||||||
@ -578,7 +578,6 @@ void TestPartitionedDataSet(vtkm::Id nPerRank,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TestStreamlineFiltersMPI()
|
void TestStreamlineFiltersMPI()
|
||||||
{
|
{
|
||||||
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
|
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
// PURPOSE. See the above copyright notice for more information.
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/Algorithm.h>
|
||||||
#include <vtkm/filter/MapFieldPermutation.h>
|
#include <vtkm/filter/MapFieldPermutation.h>
|
||||||
#include <vtkm/filter/geometry_refinement/Tetrahedralize.h>
|
#include <vtkm/filter/geometry_refinement/Tetrahedralize.h>
|
||||||
#include <vtkm/filter/geometry_refinement/worklet/Tetrahedralize.h>
|
#include <vtkm/filter/geometry_refinement/worklet/Tetrahedralize.h>
|
||||||
@ -41,6 +42,18 @@ VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct IsShapeTetra
|
||||||
|
{
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
bool operator()(vtkm::UInt8 shape) const { return shape == vtkm::CELL_SHAPE_TETRA; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryAnd
|
||||||
|
{
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
bool operator()(bool u, bool v) const { return u && v; }
|
||||||
|
};
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -53,14 +66,58 @@ VTKM_CONT vtkm::cont::DataSet Tetrahedralize::DoExecute(const vtkm::cont::DataSe
|
|||||||
{
|
{
|
||||||
const vtkm::cont::UnknownCellSet& inCellSet = input.GetCellSet();
|
const vtkm::cont::UnknownCellSet& inCellSet = input.GetCellSet();
|
||||||
|
|
||||||
vtkm::cont::CellSetSingleType<> outCellSet;
|
// In case we already have a CellSetSingleType of tetras,
|
||||||
vtkm::worklet::Tetrahedralize worklet;
|
// don't call the worklet and return the input DataSet directly
|
||||||
vtkm::cont::CastAndCall(inCellSet,
|
if (inCellSet.CanConvert<vtkm::cont::CellSetSingleType<>>() &&
|
||||||
[&](const auto& concrete) { outCellSet = worklet.Run(concrete); });
|
inCellSet.AsCellSet<vtkm::cont::CellSetSingleType<>>().GetCellShapeAsId() ==
|
||||||
|
vtkm::CellShapeTagTetra::Id)
|
||||||
|
{
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); };
|
vtkm::cont::CellSetSingleType<> outCellSet;
|
||||||
// create the output dataset (without a CoordinateSystem).
|
vtkm::cont::DataSet output;
|
||||||
vtkm::cont::DataSet output = this->CreateResult(input, outCellSet, mapper);
|
|
||||||
|
// Optimization in case we only have tetras in the CellSet
|
||||||
|
bool allTetras = false;
|
||||||
|
if (inCellSet.CanConvert<vtkm::cont::CellSetExplicit<>>())
|
||||||
|
{
|
||||||
|
vtkm::cont::CellSetExplicit<> inCellSetExplicit =
|
||||||
|
inCellSet.AsCellSet<vtkm::cont::CellSetExplicit<>>();
|
||||||
|
|
||||||
|
auto shapeArray = inCellSetExplicit.GetShapesArray(vtkm::TopologyElementTagCell(),
|
||||||
|
vtkm::TopologyElementTagPoint());
|
||||||
|
auto isCellTetraArray = vtkm::cont::make_ArrayHandleTransform(shapeArray, IsShapeTetra{});
|
||||||
|
|
||||||
|
allTetras = vtkm::cont::Algorithm::Reduce(isCellTetraArray, true, BinaryAnd{});
|
||||||
|
|
||||||
|
if (allTetras)
|
||||||
|
{
|
||||||
|
// Reuse the input's connectivity array
|
||||||
|
outCellSet.Fill(inCellSet.GetNumberOfPoints(),
|
||||||
|
vtkm::CellShapeTagTetra::Id,
|
||||||
|
4,
|
||||||
|
inCellSetExplicit.GetConnectivityArray(vtkm::TopologyElementTagCell(),
|
||||||
|
vtkm::TopologyElementTagPoint()));
|
||||||
|
|
||||||
|
// Copy all fields from the input
|
||||||
|
output = this->CreateResult(input, outCellSet, [&](auto& result, const auto& f) {
|
||||||
|
result.AddField(f);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allTetras)
|
||||||
|
{
|
||||||
|
vtkm::worklet::Tetrahedralize worklet;
|
||||||
|
vtkm::cont::CastAndCall(inCellSet,
|
||||||
|
[&](const auto& concrete) { outCellSet = worklet.Run(concrete); });
|
||||||
|
|
||||||
|
auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); };
|
||||||
|
// create the output dataset (without a CoordinateSystem).
|
||||||
|
output = this->CreateResult(input, outCellSet, mapper);
|
||||||
|
}
|
||||||
|
|
||||||
// We did not change the geometry of the input dataset at all. Just attach coordinate system
|
// We did not change the geometry of the input dataset at all. Just attach coordinate system
|
||||||
// of input dataset to output dataset.
|
// of input dataset to output dataset.
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
// PURPOSE. See the above copyright notice for more information.
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/Algorithm.h>
|
||||||
#include <vtkm/filter/MapFieldPermutation.h>
|
#include <vtkm/filter/MapFieldPermutation.h>
|
||||||
#include <vtkm/filter/geometry_refinement/Triangulate.h>
|
#include <vtkm/filter/geometry_refinement/Triangulate.h>
|
||||||
#include <vtkm/filter/geometry_refinement/worklet/Triangulate.h>
|
#include <vtkm/filter/geometry_refinement/worklet/Triangulate.h>
|
||||||
@ -42,6 +43,18 @@ VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct IsShapeTriangle
|
||||||
|
{
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
bool operator()(vtkm::UInt8 shape) const { return shape == vtkm::CELL_SHAPE_TRIANGLE; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryAnd
|
||||||
|
{
|
||||||
|
VTKM_EXEC_CONT
|
||||||
|
bool operator()(bool u, bool v) const { return u && v; }
|
||||||
|
};
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -54,15 +67,57 @@ VTKM_CONT vtkm::cont::DataSet Triangulate::DoExecute(const vtkm::cont::DataSet&
|
|||||||
{
|
{
|
||||||
const vtkm::cont::UnknownCellSet& inCellSet = input.GetCellSet();
|
const vtkm::cont::UnknownCellSet& inCellSet = input.GetCellSet();
|
||||||
|
|
||||||
|
// In case we already have a CellSetSingleType of tetras,
|
||||||
|
// don't call the worklet and return the input DataSet directly
|
||||||
|
if (inCellSet.CanConvert<vtkm::cont::CellSetSingleType<>>() &&
|
||||||
|
inCellSet.AsCellSet<vtkm::cont::CellSetSingleType<>>().GetCellShapeAsId() ==
|
||||||
|
vtkm::CellShapeTagTriangle::Id)
|
||||||
|
{
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
vtkm::cont::CellSetSingleType<> outCellSet;
|
vtkm::cont::CellSetSingleType<> outCellSet;
|
||||||
vtkm::worklet::Triangulate worklet;
|
vtkm::cont::DataSet output;
|
||||||
|
|
||||||
vtkm::cont::CastAndCall(inCellSet,
|
// Optimization in case we only have triangles in the CellSet
|
||||||
[&](const auto& concrete) { outCellSet = worklet.Run(concrete); });
|
bool allTriangles = false;
|
||||||
|
if (inCellSet.CanConvert<vtkm::cont::CellSetExplicit<>>())
|
||||||
|
{
|
||||||
|
vtkm::cont::CellSetExplicit<> inCellSetExplicit =
|
||||||
|
inCellSet.AsCellSet<vtkm::cont::CellSetExplicit<>>();
|
||||||
|
|
||||||
auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); };
|
auto shapeArray = inCellSetExplicit.GetShapesArray(vtkm::TopologyElementTagCell(),
|
||||||
// create the output dataset (without a CoordinateSystem).
|
vtkm::TopologyElementTagPoint());
|
||||||
vtkm::cont::DataSet output = this->CreateResult(input, outCellSet, mapper);
|
auto isCellTriangleArray = vtkm::cont::make_ArrayHandleTransform(shapeArray, IsShapeTriangle{});
|
||||||
|
allTriangles = vtkm::cont::Algorithm::Reduce(isCellTriangleArray, true, BinaryAnd{});
|
||||||
|
|
||||||
|
if (allTriangles)
|
||||||
|
{
|
||||||
|
// Reuse the input's connectivity array
|
||||||
|
outCellSet.Fill(inCellSet.GetNumberOfPoints(),
|
||||||
|
vtkm::CellShapeTagTriangle::Id,
|
||||||
|
3,
|
||||||
|
inCellSetExplicit.GetConnectivityArray(vtkm::TopologyElementTagCell(),
|
||||||
|
vtkm::TopologyElementTagPoint()));
|
||||||
|
|
||||||
|
// Copy all fields from the input
|
||||||
|
output = this->CreateResult(input, outCellSet, [&](auto& result, const auto& f) {
|
||||||
|
result.AddField(f);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allTriangles)
|
||||||
|
{
|
||||||
|
vtkm::worklet::Triangulate worklet;
|
||||||
|
vtkm::cont::CastAndCall(inCellSet,
|
||||||
|
[&](const auto& concrete) { outCellSet = worklet.Run(concrete); });
|
||||||
|
|
||||||
|
auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); };
|
||||||
|
// create the output dataset (without a CoordinateSystem).
|
||||||
|
output = this->CreateResult(input, outCellSet, mapper);
|
||||||
|
}
|
||||||
|
|
||||||
// We did not change the geometry of the input dataset at all. Just attach coordinate system
|
// We did not change the geometry of the input dataset at all. Just attach coordinate system
|
||||||
// of input dataset to output dataset.
|
// of input dataset to output dataset.
|
||||||
|
@ -234,7 +234,7 @@ void TestWithStructuredData()
|
|||||||
contour.SetIsoValue(192);
|
contour.SetIsoValue(192);
|
||||||
contour.SetMergeDuplicatePoints(true);
|
contour.SetMergeDuplicatePoints(true);
|
||||||
contour.SetGenerateNormals(true);
|
contour.SetGenerateNormals(true);
|
||||||
contour.SetComputeFastNormalsForStructured(true);
|
contour.SetComputeFastNormals(true);
|
||||||
contour.SetNormalArrayName("normals");
|
contour.SetNormalArrayName("normals");
|
||||||
dataSet = contour.Execute(dataSet);
|
dataSet = contour.Execute(dataSet);
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
// PURPOSE. See the above copyright notice for more information.
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/DataSetBuilderExplicit.h>
|
||||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||||
#include <vtkm/cont/testing/Testing.h>
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
|
||||||
@ -67,10 +68,56 @@ public:
|
|||||||
VTKM_TEST_ASSERT(outData.ReadPortal().Get(10) == 130.5f, "Wrong cell field data");
|
VTKM_TEST_ASSERT(outData.ReadPortal().Get(10) == 130.5f, "Wrong cell field data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestCellSetSingleTypeTetra() const
|
||||||
|
{
|
||||||
|
vtkm::cont::DataSet dataset;
|
||||||
|
vtkm::cont::CellSetSingleType<> cellSet;
|
||||||
|
|
||||||
|
auto connectivity = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 1, 2, 3, 3, 2, 1, 4 });
|
||||||
|
cellSet.Fill(5, vtkm::CELL_SHAPE_TETRA, 4, connectivity);
|
||||||
|
|
||||||
|
dataset.SetCellSet(cellSet);
|
||||||
|
|
||||||
|
vtkm::filter::geometry_refinement::Tetrahedralize tetrahedralize;
|
||||||
|
vtkm::cont::DataSet output = tetrahedralize.Execute(dataset);
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(dataset.GetCellSet().GetCellSetBase() == output.GetCellSet().GetCellSetBase(),
|
||||||
|
"Pointer to the CellSetSingleType has changed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCellSetExplicitTetra() const
|
||||||
|
{
|
||||||
|
std::vector<vtkm::Vec3f_32> coords{
|
||||||
|
vtkm::Vec3f_32(0.0f, 0.0f, 0.0f), vtkm::Vec3f_32(2.0f, 0.0f, 0.0f),
|
||||||
|
vtkm::Vec3f_32(2.0f, 4.0f, 0.0f), vtkm::Vec3f_32(0.0f, 4.0f, 0.0f),
|
||||||
|
vtkm::Vec3f_32(1.0f, 0.0f, 3.0f),
|
||||||
|
};
|
||||||
|
std::vector<vtkm::UInt8> shapes{ vtkm::CELL_SHAPE_TETRA, vtkm::CELL_SHAPE_TETRA };
|
||||||
|
std::vector<vtkm::IdComponent> indices{ 4, 4 };
|
||||||
|
std::vector<vtkm::Id> connectivity{ 0, 1, 2, 3, 1, 2, 3, 4 };
|
||||||
|
|
||||||
|
vtkm::cont::DataSetBuilderExplicit dsb;
|
||||||
|
vtkm::cont::DataSet dataset = dsb.Create(coords, shapes, indices, connectivity);
|
||||||
|
|
||||||
|
vtkm::filter::geometry_refinement::Tetrahedralize tetrahedralize;
|
||||||
|
vtkm::cont::DataSet output = tetrahedralize.Execute(dataset);
|
||||||
|
vtkm::cont::UnknownCellSet outputCellSet = output.GetCellSet();
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(outputCellSet.IsType<vtkm::cont::CellSetSingleType<>>(),
|
||||||
|
"Output CellSet is not CellSetSingleType");
|
||||||
|
VTKM_TEST_ASSERT(output.GetNumberOfCells() == 2, "Wrong number of cells");
|
||||||
|
VTKM_TEST_ASSERT(outputCellSet.GetCellShape(0) == vtkm::CellShapeTagTetra::Id,
|
||||||
|
"Cell is not tetra");
|
||||||
|
VTKM_TEST_ASSERT(outputCellSet.GetCellShape(1) == vtkm::CellShapeTagTetra::Id,
|
||||||
|
"Cell is not tetra");
|
||||||
|
}
|
||||||
|
|
||||||
void operator()() const
|
void operator()() const
|
||||||
{
|
{
|
||||||
this->TestStructured();
|
this->TestStructured();
|
||||||
this->TestExplicit();
|
this->TestExplicit();
|
||||||
|
this->TestCellSetSingleTypeTetra();
|
||||||
|
this->TestCellSetExplicitTetra();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
// PURPOSE. See the above copyright notice for more information.
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include <vtkm/cont/DataSetBuilderExplicit.h>
|
||||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||||
#include <vtkm/cont/testing/Testing.h>
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
|
||||||
@ -61,10 +62,55 @@ public:
|
|||||||
VTKM_TEST_ASSERT(outData.ReadPortal().Get(6) == 3.f, "Wrong cell field data");
|
VTKM_TEST_ASSERT(outData.ReadPortal().Get(6) == 3.f, "Wrong cell field data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestCellSetSingleTypeTriangle() const
|
||||||
|
{
|
||||||
|
vtkm::cont::DataSet dataset;
|
||||||
|
vtkm::cont::CellSetSingleType<> cellSet;
|
||||||
|
|
||||||
|
auto connectivity = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 1, 2, 1, 2, 3 });
|
||||||
|
cellSet.Fill(4, vtkm::CELL_SHAPE_TRIANGLE, 3, connectivity);
|
||||||
|
|
||||||
|
dataset.SetCellSet(cellSet);
|
||||||
|
|
||||||
|
vtkm::filter::geometry_refinement::Triangulate triangulate;
|
||||||
|
vtkm::cont::DataSet output = triangulate.Execute(dataset);
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(dataset.GetCellSet().GetCellSetBase() == output.GetCellSet().GetCellSetBase(),
|
||||||
|
"Pointer to the CellSetSingleType has changed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCellSetExplicitTriangle() const
|
||||||
|
{
|
||||||
|
std::vector<vtkm::Vec3f_32> coords{ vtkm::Vec3f_32(0.0f, 0.0f, 0.0f),
|
||||||
|
vtkm::Vec3f_32(2.0f, 0.0f, 0.0f),
|
||||||
|
vtkm::Vec3f_32(2.0f, 4.0f, 0.0f),
|
||||||
|
vtkm::Vec3f_32(0.0f, 4.0f, 0.0f) };
|
||||||
|
std::vector<vtkm::UInt8> shapes{ vtkm::CELL_SHAPE_TRIANGLE, vtkm::CELL_SHAPE_TRIANGLE };
|
||||||
|
std::vector<vtkm::IdComponent> indices{ 3, 3 };
|
||||||
|
std::vector<vtkm::Id> connectivity{ 0, 1, 2, 1, 2, 3 };
|
||||||
|
|
||||||
|
vtkm::cont::DataSetBuilderExplicit dsb;
|
||||||
|
vtkm::cont::DataSet dataset = dsb.Create(coords, shapes, indices, connectivity);
|
||||||
|
|
||||||
|
vtkm::filter::geometry_refinement::Triangulate triangulate;
|
||||||
|
vtkm::cont::DataSet output = triangulate.Execute(dataset);
|
||||||
|
vtkm::cont::UnknownCellSet outputCellSet = output.GetCellSet();
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(outputCellSet.IsType<vtkm::cont::CellSetSingleType<>>(),
|
||||||
|
"Output CellSet is not CellSetSingleType");
|
||||||
|
VTKM_TEST_ASSERT(output.GetNumberOfCells() == 2, "Wrong number of cells");
|
||||||
|
VTKM_TEST_ASSERT(outputCellSet.GetCellShape(0) == vtkm::CellShapeTagTriangle::Id,
|
||||||
|
"Cell is not triangular");
|
||||||
|
VTKM_TEST_ASSERT(outputCellSet.GetCellShape(1) == vtkm::CellShapeTagTriangle::Id,
|
||||||
|
"Cell is not triangular");
|
||||||
|
}
|
||||||
|
|
||||||
void operator()() const
|
void operator()() const
|
||||||
{
|
{
|
||||||
this->TestStructured();
|
this->TestStructured();
|
||||||
this->TestExplicit();
|
this->TestExplicit();
|
||||||
|
this->TestCellSetSingleTypeTriangle();
|
||||||
|
this->TestCellSetExplicitTriangle();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ WorldAnnotator::WorldAnnotator(const vtkm::rendering::Canvas* canvas)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldAnnotator::~WorldAnnotator() {}
|
|
||||||
|
|
||||||
void WorldAnnotator::AddLine(const vtkm::Vec3f_64& point0,
|
void WorldAnnotator::AddLine(const vtkm::Vec3f_64& point0,
|
||||||
const vtkm::Vec3f_64& point1,
|
const vtkm::Vec3f_64& point1,
|
||||||
vtkm::Float32 lineWidth,
|
vtkm::Float32 lineWidth,
|
||||||
@ -32,22 +30,18 @@ void WorldAnnotator::AddLine(const vtkm::Vec3f_64& point0,
|
|||||||
{
|
{
|
||||||
vtkm::Matrix<vtkm::Float32, 4, 4> transform =
|
vtkm::Matrix<vtkm::Float32, 4, 4> transform =
|
||||||
vtkm::MatrixMultiply(Canvas->GetProjection(), Canvas->GetModelView());
|
vtkm::MatrixMultiply(Canvas->GetProjection(), Canvas->GetModelView());
|
||||||
vtkm::rendering::WorldAnnotator* self = const_cast<vtkm::rendering::WorldAnnotator*>(this);
|
LineRenderer renderer(Canvas, transform, &(this->LineBatcher));
|
||||||
LineRenderer renderer(Canvas, transform, &(self->LineBatcher));
|
|
||||||
renderer.RenderLine(point0, point1, lineWidth, color);
|
renderer.RenderLine(point0, point1, lineWidth, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldAnnotator::BeginLineRenderingBatch() const
|
void WorldAnnotator::BeginLineRenderingBatch() const
|
||||||
{
|
{
|
||||||
vtkm::rendering::WorldAnnotator* self = const_cast<vtkm::rendering::WorldAnnotator*>(this);
|
this->LineBatcher = vtkm::rendering::LineRendererBatcher();
|
||||||
self->LineBatcher = vtkm::rendering::LineRendererBatcher();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldAnnotator::EndLineRenderingBatch() const
|
void WorldAnnotator::EndLineRenderingBatch() const
|
||||||
{
|
{
|
||||||
vtkm::rendering::WorldAnnotator* self = const_cast<vtkm::rendering::WorldAnnotator*>(this);
|
this->LineBatcher.Render(this->Canvas);
|
||||||
vtkm::rendering::Canvas* canvas = const_cast<vtkm::rendering::Canvas*>(this->Canvas);
|
|
||||||
self->LineBatcher.Render(canvas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldAnnotator::AddText(const vtkm::Vec3f_32& origin,
|
void WorldAnnotator::AddText(const vtkm::Vec3f_32& origin,
|
||||||
|
@ -29,13 +29,11 @@ class VTKM_RENDERING_EXPORT WorldAnnotator
|
|||||||
public:
|
public:
|
||||||
WorldAnnotator(const vtkm::rendering::Canvas* canvas);
|
WorldAnnotator(const vtkm::rendering::Canvas* canvas);
|
||||||
|
|
||||||
virtual ~WorldAnnotator();
|
void AddLine(const vtkm::Vec3f_64& point0,
|
||||||
|
const vtkm::Vec3f_64& point1,
|
||||||
virtual void AddLine(const vtkm::Vec3f_64& point0,
|
vtkm::Float32 lineWidth,
|
||||||
const vtkm::Vec3f_64& point1,
|
const vtkm::rendering::Color& color,
|
||||||
vtkm::Float32 lineWidth,
|
bool inFront = false) const;
|
||||||
const vtkm::rendering::Color& color,
|
|
||||||
bool inFront = false) const;
|
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
void AddLine(vtkm::Float64 x0,
|
void AddLine(vtkm::Float64 x0,
|
||||||
@ -58,14 +56,14 @@ public:
|
|||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
void EndLineRenderingBatch() const;
|
void EndLineRenderingBatch() const;
|
||||||
|
|
||||||
virtual void AddText(const vtkm::Vec3f_32& origin,
|
void AddText(const vtkm::Vec3f_32& origin,
|
||||||
const vtkm::Vec3f_32& right,
|
const vtkm::Vec3f_32& right,
|
||||||
const vtkm::Vec3f_32& up,
|
const vtkm::Vec3f_32& up,
|
||||||
vtkm::Float32 scale,
|
vtkm::Float32 scale,
|
||||||
const vtkm::Vec2f_32& anchor,
|
const vtkm::Vec2f_32& anchor,
|
||||||
const vtkm::rendering::Color& color,
|
const vtkm::rendering::Color& color,
|
||||||
const std::string& text,
|
const std::string& text,
|
||||||
const vtkm::Float32 depth = 0.f) const;
|
const vtkm::Float32 depth = 0.f) const;
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
void AddText(vtkm::Float32 originX,
|
void AddText(vtkm::Float32 originX,
|
||||||
@ -94,7 +92,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const vtkm::rendering::Canvas* Canvas;
|
const vtkm::rendering::Canvas* Canvas;
|
||||||
vtkm::rendering::LineRendererBatcher LineBatcher;
|
mutable vtkm::rendering::LineRendererBatcher LineBatcher;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} //namespace vtkm::rendering
|
} //namespace vtkm::rendering
|
||||||
|
@ -9,22 +9,22 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
#include <vtkm/rendering/raytracing/VolumeRendererStructured.h>
|
#include <vtkm/rendering/raytracing/VolumeRendererStructured.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
||||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||||
|
#include <vtkm/cont/CellLocatorRectilinearGrid.h>
|
||||||
|
#include <vtkm/cont/CellLocatorUniformGrid.h>
|
||||||
#include <vtkm/cont/CellSetStructured.h>
|
#include <vtkm/cont/CellSetStructured.h>
|
||||||
#include <vtkm/cont/ColorTable.h>
|
#include <vtkm/cont/ColorTable.h>
|
||||||
#include <vtkm/cont/ErrorBadValue.h>
|
#include <vtkm/cont/ErrorBadValue.h>
|
||||||
|
#include <vtkm/cont/Invoker.h>
|
||||||
#include <vtkm/cont/Timer.h>
|
#include <vtkm/cont/Timer.h>
|
||||||
#include <vtkm/cont/TryExecute.h>
|
#include <vtkm/cont/TryExecute.h>
|
||||||
#include <vtkm/rendering/raytracing/Camera.h>
|
|
||||||
#include <vtkm/rendering/raytracing/Logger.h>
|
#include <vtkm/rendering/raytracing/Logger.h>
|
||||||
#include <vtkm/rendering/raytracing/Ray.h>
|
#include <vtkm/rendering/raytracing/Ray.h>
|
||||||
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
||||||
#include <vtkm/worklet/DispatcherMapField.h>
|
|
||||||
#include <vtkm/worklet/WorkletMapField.h>
|
#include <vtkm/worklet/WorkletMapField.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -33,273 +33,157 @@ namespace rendering
|
|||||||
{
|
{
|
||||||
namespace raytracing
|
namespace raytracing
|
||||||
{
|
{
|
||||||
|
using DefaultHandle = vtkm::cont::ArrayHandle<vtkm::FloatDefault>;
|
||||||
|
using CartesianArrayHandle =
|
||||||
|
vtkm::cont::ArrayHandleCartesianProduct<DefaultHandle, DefaultHandle, DefaultHandle>;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename Device>
|
template <typename Device, typename Derived>
|
||||||
class RectilinearLocator
|
class LocatorAdapterBase
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
using DefaultHandle = vtkm::cont::ArrayHandle<vtkm::FloatDefault>;
|
public:
|
||||||
using CartesianArrayHandle =
|
VTKM_EXEC
|
||||||
vtkm::cont::ArrayHandleCartesianProduct<DefaultHandle, DefaultHandle, DefaultHandle>;
|
inline bool IsInside(const vtkm::Vec3f_32& point) const
|
||||||
|
{
|
||||||
|
return static_cast<const Derived*>(this)->Locator.IsInside(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assumes point inside the data set
|
||||||
|
VTKM_EXEC
|
||||||
|
inline void LocateCell(vtkm::Id3& cell,
|
||||||
|
const vtkm::Vec3f_32& point,
|
||||||
|
vtkm::Vec3f_32& invSpacing,
|
||||||
|
vtkm::Vec3f& parametric) const
|
||||||
|
{
|
||||||
|
vtkm::Id cellId{};
|
||||||
|
auto self = static_cast<const Derived*>(this);
|
||||||
|
self->Locator.FindCell(point, cellId, parametric);
|
||||||
|
cell = self->Conn.FlatToLogicalToIndex(cellId);
|
||||||
|
self->ComputeInvSpacing(cell, point, invSpacing, parametric);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
inline void GetCellIndices(const vtkm::Id3& cell, vtkm::Vec<vtkm::Id, 8>& cellIndices) const
|
||||||
|
{
|
||||||
|
cellIndices = static_cast<const Derived*>(this)->Conn.GetIndices(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
inline vtkm::Id GetCellIndex(const vtkm::Id3& cell) const
|
||||||
|
{
|
||||||
|
return static_cast<const Derived*>(this)->Conn.LogicalToFlatToIndex(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
inline void GetPoint(const vtkm::Id& index, vtkm::Vec3f_32& point) const
|
||||||
|
{
|
||||||
|
BOUNDS_CHECK(static_cast<const Derived*>(this)->Coordinates, index);
|
||||||
|
point = static_cast<const Derived*>(this)->Coordinates.Get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
inline void GetMinPoint(const vtkm::Id3& cell, vtkm::Vec3f_32& point) const
|
||||||
|
{
|
||||||
|
const vtkm::Id pointIndex =
|
||||||
|
static_cast<const Derived*>(this)->Conn.LogicalToFlatFromIndex(cell);
|
||||||
|
point = static_cast<const Derived*>(this)->Coordinates.Get(pointIndex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Device>
|
||||||
|
class RectilinearLocatorAdapter
|
||||||
|
: public LocatorAdapterBase<Device, RectilinearLocatorAdapter<Device>>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
friend LocatorAdapterBase<Device, RectilinearLocatorAdapter<Device>>;
|
||||||
using DefaultConstHandle = typename DefaultHandle::ReadPortalType;
|
using DefaultConstHandle = typename DefaultHandle::ReadPortalType;
|
||||||
using CartesianConstPortal = typename CartesianArrayHandle::ReadPortalType;
|
using CartesianConstPortal = typename CartesianArrayHandle::ReadPortalType;
|
||||||
|
|
||||||
DefaultConstHandle CoordPortals[3];
|
|
||||||
CartesianConstPortal Coordinates;
|
CartesianConstPortal Coordinates;
|
||||||
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint, 3>
|
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint, 3>
|
||||||
Conn;
|
Conn;
|
||||||
vtkm::Id3 PointDimensions;
|
vtkm::exec::CellLocatorRectilinearGrid Locator;
|
||||||
vtkm::Vec3f_32 MinPoint;
|
|
||||||
vtkm::Vec3f_32 MaxPoint;
|
DefaultConstHandle CoordPortals[3];
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
inline void ComputeInvSpacing(vtkm::Id3& cell,
|
||||||
|
const vtkm::Vec3f_32&,
|
||||||
|
vtkm::Vec3f_32& invSpacing,
|
||||||
|
vtkm::Vec3f) const
|
||||||
|
{
|
||||||
|
vtkm::Vec3f p0{ CoordPortals[0].Get(cell[0]),
|
||||||
|
CoordPortals[1].Get(cell[1]),
|
||||||
|
CoordPortals[2].Get(cell[2]) };
|
||||||
|
vtkm::Vec3f p1{ CoordPortals[0].Get(cell[0] + 1),
|
||||||
|
CoordPortals[1].Get(cell[1] + 1),
|
||||||
|
CoordPortals[2].Get(cell[2] + 1) };
|
||||||
|
invSpacing = 1.f / (p1 - p0);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RectilinearLocator(const CartesianArrayHandle& coordinates,
|
RectilinearLocatorAdapter(const CartesianArrayHandle& coordinates,
|
||||||
vtkm::cont::CellSetStructured<3>& cellset,
|
vtkm::cont::CellSetStructured<3>& cellset,
|
||||||
vtkm::cont::Token& token)
|
vtkm::cont::CellLocatorRectilinearGrid& locator,
|
||||||
|
vtkm::cont::Token& token)
|
||||||
: Coordinates(coordinates.PrepareForInput(Device(), token))
|
: Coordinates(coordinates.PrepareForInput(Device(), token))
|
||||||
, Conn(cellset.PrepareForInput(Device(),
|
, Conn(cellset.PrepareForInput(Device(),
|
||||||
vtkm::TopologyElementTagCell(),
|
vtkm::TopologyElementTagCell(),
|
||||||
vtkm::TopologyElementTagPoint(),
|
vtkm::TopologyElementTagPoint(),
|
||||||
token))
|
token))
|
||||||
|
, Locator((locator.PrepareForExecution(Device(), token)))
|
||||||
{
|
{
|
||||||
CoordPortals[0] = Coordinates.GetFirstPortal();
|
CoordPortals[0] = Coordinates.GetFirstPortal();
|
||||||
CoordPortals[1] = Coordinates.GetSecondPortal();
|
CoordPortals[1] = Coordinates.GetSecondPortal();
|
||||||
CoordPortals[2] = Coordinates.GetThirdPortal();
|
CoordPortals[2] = Coordinates.GetThirdPortal();
|
||||||
PointDimensions = Conn.GetPointDimensions();
|
|
||||||
MinPoint[0] = static_cast<vtkm::Float32>(coordinates.ReadPortal().GetFirstPortal().Get(0));
|
|
||||||
MinPoint[1] = static_cast<vtkm::Float32>(coordinates.ReadPortal().GetSecondPortal().Get(0));
|
|
||||||
MinPoint[2] = static_cast<vtkm::Float32>(coordinates.ReadPortal().GetThirdPortal().Get(0));
|
|
||||||
|
|
||||||
MaxPoint[0] = static_cast<vtkm::Float32>(
|
|
||||||
coordinates.ReadPortal().GetFirstPortal().Get(PointDimensions[0] - 1));
|
|
||||||
MaxPoint[1] = static_cast<vtkm::Float32>(
|
|
||||||
coordinates.ReadPortal().GetSecondPortal().Get(PointDimensions[1] - 1));
|
|
||||||
MaxPoint[2] = static_cast<vtkm::Float32>(
|
|
||||||
coordinates.ReadPortal().GetThirdPortal().Get(PointDimensions[2] - 1));
|
|
||||||
}
|
}
|
||||||
|
}; // class RectilinearLocatorAdapter
|
||||||
VTKM_EXEC
|
|
||||||
inline bool IsInside(const vtkm::Vec3f_32& point) const
|
|
||||||
{
|
|
||||||
bool inside = true;
|
|
||||||
if (point[0] < MinPoint[0] || point[0] > MaxPoint[0])
|
|
||||||
inside = false;
|
|
||||||
if (point[1] < MinPoint[1] || point[1] > MaxPoint[1])
|
|
||||||
inside = false;
|
|
||||||
if (point[2] < MinPoint[2] || point[2] > MaxPoint[2])
|
|
||||||
inside = false;
|
|
||||||
return inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline void GetCellIndices(const vtkm::Id3& cell, vtkm::Vec<vtkm::Id, 8>& cellIndices) const
|
|
||||||
{
|
|
||||||
cellIndices[0] = (cell[2] * PointDimensions[1] + cell[1]) * PointDimensions[0] + cell[0];
|
|
||||||
cellIndices[1] = cellIndices[0] + 1;
|
|
||||||
cellIndices[2] = cellIndices[1] + PointDimensions[0];
|
|
||||||
cellIndices[3] = cellIndices[2] - 1;
|
|
||||||
cellIndices[4] = cellIndices[0] + PointDimensions[0] * PointDimensions[1];
|
|
||||||
cellIndices[5] = cellIndices[4] + 1;
|
|
||||||
cellIndices[6] = cellIndices[5] + PointDimensions[0];
|
|
||||||
cellIndices[7] = cellIndices[6] - 1;
|
|
||||||
} // GetCellIndices
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assumes point inside the data set
|
|
||||||
//
|
|
||||||
VTKM_EXEC
|
|
||||||
inline void LocateCell(vtkm::Id3& cell,
|
|
||||||
const vtkm::Vec3f_32& point,
|
|
||||||
vtkm::Vec3f_32& invSpacing) const
|
|
||||||
{
|
|
||||||
for (vtkm::Int32 dim = 0; dim < 3; ++dim)
|
|
||||||
{
|
|
||||||
if (point[dim] <= MinPoint[dim])
|
|
||||||
{
|
|
||||||
cell[dim] = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// When searching for points, we consider the max value of the cell
|
|
||||||
// to be apart of the next cell. If the point falls on the boundary of the
|
|
||||||
// data set, then it is technically inside a cell. This checks for that case
|
|
||||||
//
|
|
||||||
if (point[dim] >= MaxPoint[dim])
|
|
||||||
{
|
|
||||||
cell[dim] = PointDimensions[dim] - 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
vtkm::Float32 minVal = static_cast<vtkm::Float32>(CoordPortals[dim].Get(cell[dim]));
|
|
||||||
const vtkm::Id searchDir = (point[dim] - minVal >= 0.f) ? 1 : -1;
|
|
||||||
vtkm::Float32 maxVal = static_cast<vtkm::Float32>(CoordPortals[dim].Get(cell[dim] + 1));
|
|
||||||
|
|
||||||
while (!found)
|
|
||||||
{
|
|
||||||
if (point[dim] >= minVal && point[dim] < maxVal)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell[dim] += searchDir;
|
|
||||||
vtkm::Id nextCellId = searchDir == 1 ? cell[dim] + 1 : cell[dim];
|
|
||||||
BOUNDS_CHECK(CoordPortals[dim], nextCellId);
|
|
||||||
vtkm::Float32 next = static_cast<vtkm::Float32>(CoordPortals[dim].Get(nextCellId));
|
|
||||||
if (searchDir == 1)
|
|
||||||
{
|
|
||||||
minVal = maxVal;
|
|
||||||
maxVal = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxVal = minVal;
|
|
||||||
minVal = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
invSpacing[dim] = 1.f / (maxVal - minVal);
|
|
||||||
}
|
|
||||||
} // LocateCell
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline vtkm::Id GetCellIndex(const vtkm::Id3& cell) const
|
|
||||||
{
|
|
||||||
return (cell[2] * (PointDimensions[1] - 1) + cell[1]) * (PointDimensions[0] - 1) + cell[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline void GetPoint(const vtkm::Id& index, vtkm::Vec3f_32& point) const
|
|
||||||
{
|
|
||||||
BOUNDS_CHECK(Coordinates, index);
|
|
||||||
point = Coordinates.Get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline void GetMinPoint(const vtkm::Id3& cell, vtkm::Vec3f_32& point) const
|
|
||||||
{
|
|
||||||
const vtkm::Id pointIndex =
|
|
||||||
(cell[2] * PointDimensions[1] + cell[1]) * PointDimensions[0] + cell[0];
|
|
||||||
point = Coordinates.Get(pointIndex);
|
|
||||||
}
|
|
||||||
}; // class RectilinearLocator
|
|
||||||
|
|
||||||
template <typename Device>
|
template <typename Device>
|
||||||
class UniformLocator
|
class UniformLocatorAdapter : public LocatorAdapterBase<Device, UniformLocatorAdapter<Device>>
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
|
friend LocatorAdapterBase<Device, UniformLocatorAdapter<Device>>;
|
||||||
using UniformArrayHandle = vtkm::cont::ArrayHandleUniformPointCoordinates;
|
using UniformArrayHandle = vtkm::cont::ArrayHandleUniformPointCoordinates;
|
||||||
using UniformConstPortal = typename UniformArrayHandle::ReadPortalType;
|
using UniformConstPortal = typename UniformArrayHandle::ReadPortalType;
|
||||||
|
|
||||||
vtkm::Id3 PointDimensions;
|
|
||||||
vtkm::Vec3f_32 Origin;
|
|
||||||
vtkm::Vec3f_32 InvSpacing;
|
|
||||||
vtkm::Vec3f_32 MaxPoint;
|
|
||||||
UniformConstPortal Coordinates;
|
UniformConstPortal Coordinates;
|
||||||
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint, 3>
|
vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint, 3>
|
||||||
Conn;
|
Conn;
|
||||||
|
vtkm::exec::CellLocatorUniformGrid Locator;
|
||||||
|
|
||||||
|
vtkm::Vec3f_32 InvSpacing{ 0, 0, 0 };
|
||||||
|
|
||||||
|
VTKM_EXEC
|
||||||
|
inline void ComputeInvSpacing(vtkm::Id3&,
|
||||||
|
const vtkm::Vec3f_32&,
|
||||||
|
vtkm::Vec3f_32& invSpacing,
|
||||||
|
vtkm::Vec3f&) const
|
||||||
|
{
|
||||||
|
invSpacing = InvSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UniformLocator(const UniformArrayHandle& coordinates,
|
UniformLocatorAdapter(const UniformArrayHandle& coordinates,
|
||||||
vtkm::cont::CellSetStructured<3>& cellset,
|
vtkm::cont::CellSetStructured<3>& cellset,
|
||||||
vtkm::cont::Token& token)
|
vtkm::cont::CellLocatorUniformGrid& locator,
|
||||||
|
vtkm::cont::Token& token)
|
||||||
: Coordinates(coordinates.PrepareForInput(Device(), token))
|
: Coordinates(coordinates.PrepareForInput(Device(), token))
|
||||||
, Conn(cellset.PrepareForInput(Device(),
|
, Conn(cellset.PrepareForInput(Device(),
|
||||||
vtkm::TopologyElementTagCell(),
|
vtkm::TopologyElementTagCell(),
|
||||||
vtkm::TopologyElementTagPoint(),
|
vtkm::TopologyElementTagPoint(),
|
||||||
token))
|
token))
|
||||||
|
, Locator(locator.PrepareForExecution(Device(), token))
|
||||||
{
|
{
|
||||||
Origin = Coordinates.GetOrigin();
|
|
||||||
PointDimensions = Conn.GetPointDimensions();
|
|
||||||
vtkm::Vec3f_32 spacing = Coordinates.GetSpacing();
|
vtkm::Vec3f_32 spacing = Coordinates.GetSpacing();
|
||||||
|
|
||||||
vtkm::Vec3f_32 unitLength;
|
|
||||||
unitLength[0] = static_cast<vtkm::Float32>(PointDimensions[0] - 1);
|
|
||||||
unitLength[1] = static_cast<vtkm::Float32>(PointDimensions[1] - 1);
|
|
||||||
unitLength[2] = static_cast<vtkm::Float32>(PointDimensions[2] - 1);
|
|
||||||
MaxPoint = Origin + spacing * unitLength;
|
|
||||||
InvSpacing[0] = 1.f / spacing[0];
|
InvSpacing[0] = 1.f / spacing[0];
|
||||||
InvSpacing[1] = 1.f / spacing[1];
|
InvSpacing[1] = 1.f / spacing[1];
|
||||||
InvSpacing[2] = 1.f / spacing[2];
|
InvSpacing[2] = 1.f / spacing[2];
|
||||||
}
|
}
|
||||||
|
}; // class UniformLocatorAdapter
|
||||||
VTKM_EXEC
|
|
||||||
inline bool IsInside(const vtkm::Vec3f_32& point) const
|
|
||||||
{
|
|
||||||
bool inside = true;
|
|
||||||
if (point[0] < Origin[0] || point[0] > MaxPoint[0])
|
|
||||||
inside = false;
|
|
||||||
if (point[1] < Origin[1] || point[1] > MaxPoint[1])
|
|
||||||
inside = false;
|
|
||||||
if (point[2] < Origin[2] || point[2] > MaxPoint[2])
|
|
||||||
inside = false;
|
|
||||||
return inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline void GetCellIndices(const vtkm::Id3& cell, vtkm::Vec<vtkm::Id, 8>& cellIndices) const
|
|
||||||
{
|
|
||||||
cellIndices[0] = (cell[2] * PointDimensions[1] + cell[1]) * PointDimensions[0] + cell[0];
|
|
||||||
cellIndices[1] = cellIndices[0] + 1;
|
|
||||||
cellIndices[2] = cellIndices[1] + PointDimensions[0];
|
|
||||||
cellIndices[3] = cellIndices[2] - 1;
|
|
||||||
cellIndices[4] = cellIndices[0] + PointDimensions[0] * PointDimensions[1];
|
|
||||||
cellIndices[5] = cellIndices[4] + 1;
|
|
||||||
cellIndices[6] = cellIndices[5] + PointDimensions[0];
|
|
||||||
cellIndices[7] = cellIndices[6] - 1;
|
|
||||||
} // GetCellIndices
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline vtkm::Id GetCellIndex(const vtkm::Id3& cell) const
|
|
||||||
{
|
|
||||||
return (cell[2] * (PointDimensions[1] - 1) + cell[1]) * (PointDimensions[0] - 1) + cell[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline void LocateCell(vtkm::Id3& cell,
|
|
||||||
const vtkm::Vec3f_32& point,
|
|
||||||
vtkm::Vec3f_32& invSpacing) const
|
|
||||||
{
|
|
||||||
vtkm::Vec3f_32 temp = point;
|
|
||||||
temp = temp - Origin;
|
|
||||||
temp = temp * InvSpacing;
|
|
||||||
//make sure that if we border the edges, we sample the correct cell
|
|
||||||
if (temp[0] < 0.0f)
|
|
||||||
temp[0] = 0.0f;
|
|
||||||
if (temp[1] < 0.0f)
|
|
||||||
temp[1] = 0.0f;
|
|
||||||
if (temp[2] < 0.0f)
|
|
||||||
temp[2] = 0.0f;
|
|
||||||
if (temp[0] >= vtkm::Float32(PointDimensions[0] - 1))
|
|
||||||
temp[0] = vtkm::Float32(PointDimensions[0] - 2);
|
|
||||||
if (temp[1] >= vtkm::Float32(PointDimensions[1] - 1))
|
|
||||||
temp[1] = vtkm::Float32(PointDimensions[1] - 2);
|
|
||||||
if (temp[2] >= vtkm::Float32(PointDimensions[2] - 1))
|
|
||||||
temp[2] = vtkm::Float32(PointDimensions[2] - 2);
|
|
||||||
cell = temp;
|
|
||||||
invSpacing = InvSpacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline void GetPoint(const vtkm::Id& index, vtkm::Vec3f_32& point) const
|
|
||||||
{
|
|
||||||
BOUNDS_CHECK(Coordinates, index);
|
|
||||||
point = Coordinates.Get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC
|
|
||||||
inline void GetMinPoint(const vtkm::Id3& cell, vtkm::Vec3f_32& point) const
|
|
||||||
{
|
|
||||||
const vtkm::Id pointIndex =
|
|
||||||
(cell[2] * PointDimensions[1] + cell[1]) * PointDimensions[0] + cell[0];
|
|
||||||
point = Coordinates.Get(pointIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class UniformLocator
|
|
||||||
|
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
||||||
@ -367,6 +251,7 @@ public:
|
|||||||
{
|
{
|
||||||
return; //TODO: Compact? or just image subset...
|
return; //TODO: Compact? or just image subset...
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the initial sample position;
|
//get the initial sample position;
|
||||||
vtkm::Vec3f_32 sampleLocation;
|
vtkm::Vec3f_32 sampleLocation;
|
||||||
// find the distance to the first sample
|
// find the distance to the first sample
|
||||||
@ -380,6 +265,7 @@ public:
|
|||||||
distance += SampleDistance;
|
distance += SampleDistance;
|
||||||
sampleLocation = rayOrigin + distance * rayDir;
|
sampleLocation = rayOrigin + distance * rayDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
7----------6
|
7----------6
|
||||||
/| /|
|
/| /|
|
||||||
@ -389,12 +275,10 @@ public:
|
|||||||
|/ |/ |/
|
|/ |/ |/
|
||||||
0----------1 |__ x
|
0----------1 |__ x
|
||||||
*/
|
*/
|
||||||
vtkm::Vec3f_32 bottomLeft(0, 0, 0);
|
|
||||||
bool newCell = true;
|
bool newCell = true;
|
||||||
//check to see if we left the cell
|
vtkm::Vec3f parametric{ -1.f, -1.f, -1.f };
|
||||||
vtkm::Float32 tx = 0.f;
|
vtkm::Vec3f_32 bottomLeft(0.f, 0.f, 0.f);
|
||||||
vtkm::Float32 ty = 0.f;
|
|
||||||
vtkm::Float32 tz = 0.f;
|
|
||||||
vtkm::Float32 scalar0 = 0.f;
|
vtkm::Float32 scalar0 = 0.f;
|
||||||
vtkm::Float32 scalar1minus0 = 0.f;
|
vtkm::Float32 scalar1minus0 = 0.f;
|
||||||
vtkm::Float32 scalar2minus3 = 0.f;
|
vtkm::Float32 scalar2minus3 = 0.f;
|
||||||
@ -407,29 +291,26 @@ public:
|
|||||||
vtkm::Id3 cell(0, 0, 0);
|
vtkm::Id3 cell(0, 0, 0);
|
||||||
vtkm::Vec3f_32 invSpacing(0.f, 0.f, 0.f);
|
vtkm::Vec3f_32 invSpacing(0.f, 0.f, 0.f);
|
||||||
|
|
||||||
|
|
||||||
while (Locator.IsInside(sampleLocation) && distance < maxDistance)
|
while (Locator.IsInside(sampleLocation) && distance < maxDistance)
|
||||||
{
|
{
|
||||||
vtkm::Float32 mint = vtkm::Min(tx, vtkm::Min(ty, tz));
|
vtkm::Float32 mint = vtkm::Min(parametric[0], vtkm::Min(parametric[1], parametric[2]));
|
||||||
vtkm::Float32 maxt = vtkm::Max(tx, vtkm::Max(ty, tz));
|
vtkm::Float32 maxt = vtkm::Max(parametric[0], vtkm::Max(parametric[1], parametric[2]));
|
||||||
if (maxt > 1.f || mint < 0.f)
|
if (maxt > 1.f || mint < 0.f)
|
||||||
newCell = true;
|
newCell = true;
|
||||||
|
|
||||||
if (newCell)
|
if (newCell)
|
||||||
{
|
{
|
||||||
|
|
||||||
vtkm::Vec<vtkm::Id, 8> cellIndices;
|
vtkm::Vec<vtkm::Id, 8> cellIndices;
|
||||||
Locator.LocateCell(cell, sampleLocation, invSpacing);
|
Locator.LocateCell(cell, sampleLocation, invSpacing, parametric);
|
||||||
Locator.GetCellIndices(cell, cellIndices);
|
Locator.GetCellIndices(cell, cellIndices);
|
||||||
Locator.GetPoint(cellIndices[0], bottomLeft);
|
Locator.GetPoint(cellIndices[0], bottomLeft);
|
||||||
|
|
||||||
scalar0 = vtkm::Float32(scalars.Get(cellIndices[0]));
|
scalar0 = vtkm::Float32(scalars.Get(cellIndices[0]));
|
||||||
vtkm::Float32 scalar1 = vtkm::Float32(scalars.Get(cellIndices[1]));
|
auto scalar1 = vtkm::Float32(scalars.Get(cellIndices[1]));
|
||||||
vtkm::Float32 scalar2 = vtkm::Float32(scalars.Get(cellIndices[2]));
|
auto scalar2 = vtkm::Float32(scalars.Get(cellIndices[2]));
|
||||||
scalar3 = vtkm::Float32(scalars.Get(cellIndices[3]));
|
scalar3 = vtkm::Float32(scalars.Get(cellIndices[3]));
|
||||||
scalar4 = vtkm::Float32(scalars.Get(cellIndices[4]));
|
scalar4 = vtkm::Float32(scalars.Get(cellIndices[4]));
|
||||||
vtkm::Float32 scalar5 = vtkm::Float32(scalars.Get(cellIndices[5]));
|
auto scalar5 = vtkm::Float32(scalars.Get(cellIndices[5]));
|
||||||
vtkm::Float32 scalar6 = vtkm::Float32(scalars.Get(cellIndices[6]));
|
auto scalar6 = vtkm::Float32(scalars.Get(cellIndices[6]));
|
||||||
scalar7 = vtkm::Float32(scalars.Get(cellIndices[7]));
|
scalar7 = vtkm::Float32(scalars.Get(cellIndices[7]));
|
||||||
|
|
||||||
// save ourselves a couple extra instructions
|
// save ourselves a couple extra instructions
|
||||||
@ -438,51 +319,46 @@ public:
|
|||||||
scalar1minus0 = scalar1 - scalar0;
|
scalar1minus0 = scalar1 - scalar0;
|
||||||
scalar2minus3 = scalar2 - scalar3;
|
scalar2minus3 = scalar2 - scalar3;
|
||||||
|
|
||||||
tx = (sampleLocation[0] - bottomLeft[0]) * invSpacing[0];
|
|
||||||
ty = (sampleLocation[1] - bottomLeft[1]) * invSpacing[1];
|
|
||||||
tz = (sampleLocation[2] - bottomLeft[2]) * invSpacing[2];
|
|
||||||
|
|
||||||
newCell = false;
|
newCell = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkm::Float32 lerped76 = scalar7 + tx * scalar6minus7;
|
vtkm::Float32 lerped76 = scalar7 + parametric[0] * scalar6minus7;
|
||||||
vtkm::Float32 lerped45 = scalar4 + tx * scalar5minus4;
|
vtkm::Float32 lerped45 = scalar4 + parametric[0] * scalar5minus4;
|
||||||
vtkm::Float32 lerpedTop = lerped45 + ty * (lerped76 - lerped45);
|
vtkm::Float32 lerpedTop = lerped45 + parametric[1] * (lerped76 - lerped45);
|
||||||
|
|
||||||
vtkm::Float32 lerped01 = scalar0 + tx * scalar1minus0;
|
vtkm::Float32 lerped01 = scalar0 + parametric[0] * scalar1minus0;
|
||||||
vtkm::Float32 lerped32 = scalar3 + tx * scalar2minus3;
|
vtkm::Float32 lerped32 = scalar3 + parametric[0] * scalar2minus3;
|
||||||
vtkm::Float32 lerpedBottom = lerped01 + ty * (lerped32 - lerped01);
|
vtkm::Float32 lerpedBottom = lerped01 + parametric[1] * (lerped32 - lerped01);
|
||||||
|
|
||||||
|
vtkm::Float32 finalScalar = lerpedBottom + parametric[2] * (lerpedTop - lerpedBottom);
|
||||||
|
|
||||||
vtkm::Float32 finalScalar = lerpedBottom + tz * (lerpedTop - lerpedBottom);
|
|
||||||
//normalize scalar
|
//normalize scalar
|
||||||
finalScalar = (finalScalar - MinScalar) * InverseDeltaScalar;
|
finalScalar = (finalScalar - MinScalar) * InverseDeltaScalar;
|
||||||
|
|
||||||
vtkm::Id colorIndex =
|
auto colorIndex =
|
||||||
static_cast<vtkm::Id>(finalScalar * static_cast<vtkm::Float32>(ColorMapSize));
|
static_cast<vtkm::Id>(finalScalar * static_cast<vtkm::Float32>(ColorMapSize));
|
||||||
if (colorIndex < 0)
|
if (colorIndex < 0)
|
||||||
colorIndex = 0;
|
colorIndex = 0;
|
||||||
if (colorIndex > ColorMapSize)
|
if (colorIndex > ColorMapSize)
|
||||||
colorIndex = ColorMapSize;
|
colorIndex = ColorMapSize;
|
||||||
|
|
||||||
vtkm::Vec4f_32 sampleColor = ColorMap.Get(colorIndex);
|
vtkm::Vec4f_32 sampleColor = ColorMap.Get(colorIndex);
|
||||||
|
|
||||||
//composite
|
//composite
|
||||||
sampleColor[3] *= (1.f - color[3]);
|
vtkm::Float32 alpha = sampleColor[3] * (1.f - color[3]);
|
||||||
color[0] = color[0] + sampleColor[0] * sampleColor[3];
|
color[0] = color[0] + sampleColor[0] * alpha;
|
||||||
color[1] = color[1] + sampleColor[1] * sampleColor[3];
|
color[1] = color[1] + sampleColor[1] * alpha;
|
||||||
color[2] = color[2] + sampleColor[2] * sampleColor[3];
|
color[2] = color[2] + sampleColor[2] * alpha;
|
||||||
color[3] = sampleColor[3] + color[3];
|
color[3] = alpha + color[3];
|
||||||
|
|
||||||
|
// terminate the ray early if it became completely opaque.
|
||||||
|
if (color[3] >= 1.f)
|
||||||
|
break;
|
||||||
|
|
||||||
//advance
|
//advance
|
||||||
distance += SampleDistance;
|
distance += SampleDistance;
|
||||||
sampleLocation = sampleLocation + SampleDistance * rayDir;
|
sampleLocation = sampleLocation + SampleDistance * rayDir;
|
||||||
|
|
||||||
//this is linear could just do an addition
|
parametric = (sampleLocation - bottomLeft) * invSpacing;
|
||||||
tx = (sampleLocation[0] - bottomLeft[0]) * invSpacing[0];
|
|
||||||
ty = (sampleLocation[1] - bottomLeft[1]) * invSpacing[1];
|
|
||||||
tz = (sampleLocation[2] - bottomLeft[2]) * invSpacing[2];
|
|
||||||
|
|
||||||
if (color[3] >= 1.f)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
color[0] = vtkm::Min(color[0], 1.f);
|
color[0] = vtkm::Min(color[0], 1.f);
|
||||||
@ -560,7 +436,10 @@ public:
|
|||||||
color[3] = colorBuffer.Get(pixelIndex * 4 + 3);
|
color[3] = colorBuffer.Get(pixelIndex * 4 + 3);
|
||||||
|
|
||||||
if (minDistance == -1.f)
|
if (minDistance == -1.f)
|
||||||
|
{
|
||||||
return; //TODO: Compact? or just image subset...
|
return; //TODO: Compact? or just image subset...
|
||||||
|
}
|
||||||
|
|
||||||
//get the initial sample position;
|
//get the initial sample position;
|
||||||
vtkm::Vec3f_32 sampleLocation;
|
vtkm::Vec3f_32 sampleLocation;
|
||||||
// find the distance to the first sample
|
// find the distance to the first sample
|
||||||
@ -585,38 +464,37 @@ public:
|
|||||||
0----------1 |__ x
|
0----------1 |__ x
|
||||||
*/
|
*/
|
||||||
bool newCell = true;
|
bool newCell = true;
|
||||||
vtkm::Float32 tx = 2.f;
|
vtkm::Vec3f parametric{ -1.f, -1.f, -1.f };
|
||||||
vtkm::Float32 ty = 2.f;
|
|
||||||
vtkm::Float32 tz = 2.f;
|
|
||||||
vtkm::Float32 scalar0 = 0.f;
|
vtkm::Float32 scalar0 = 0.f;
|
||||||
vtkm::Vec4f_32 sampleColor(0.f, 0.f, 0.f, 0.f);
|
vtkm::Vec4f_32 sampleColor(0.f, 0.f, 0.f, 0.f);
|
||||||
vtkm::Vec3f_32 bottomLeft(0.f, 0.f, 0.f);
|
vtkm::Vec3f_32 bottomLeft(0.f, 0.f, 0.f);
|
||||||
vtkm::Vec3f_32 invSpacing(0.f, 0.f, 0.f);
|
|
||||||
vtkm::Id3 cell(0, 0, 0);
|
vtkm::Id3 cell(0, 0, 0);
|
||||||
|
vtkm::Vec3f_32 invSpacing(0.f, 0.f, 0.f);
|
||||||
|
|
||||||
while (Locator.IsInside(sampleLocation) && distance < maxDistance)
|
while (Locator.IsInside(sampleLocation) && distance < maxDistance)
|
||||||
{
|
{
|
||||||
vtkm::Float32 mint = vtkm::Min(tx, vtkm::Min(ty, tz));
|
vtkm::Float32 mint = vtkm::Min(parametric[0], vtkm::Min(parametric[1], parametric[2]));
|
||||||
vtkm::Float32 maxt = vtkm::Max(tx, vtkm::Max(ty, tz));
|
vtkm::Float32 maxt = vtkm::Max(parametric[0], vtkm::Max(parametric[1], parametric[2]));
|
||||||
if (maxt > 1.f || mint < 0.f)
|
if (maxt > 1.f || mint < 0.f)
|
||||||
newCell = true;
|
newCell = true;
|
||||||
if (newCell)
|
if (newCell)
|
||||||
{
|
{
|
||||||
Locator.LocateCell(cell, sampleLocation, invSpacing);
|
Locator.LocateCell(cell, sampleLocation, invSpacing, parametric);
|
||||||
vtkm::Id cellId = Locator.GetCellIndex(cell);
|
vtkm::Id cellId = Locator.GetCellIndex(cell);
|
||||||
|
Locator.GetMinPoint(cell, bottomLeft);
|
||||||
|
|
||||||
scalar0 = vtkm::Float32(scalars.Get(cellId));
|
scalar0 = vtkm::Float32(scalars.Get(cellId));
|
||||||
vtkm::Float32 normalizedScalar = (scalar0 - MinScalar) * InverseDeltaScalar;
|
vtkm::Float32 normalizedScalar = (scalar0 - MinScalar) * InverseDeltaScalar;
|
||||||
vtkm::Id colorIndex =
|
|
||||||
|
auto colorIndex =
|
||||||
static_cast<vtkm::Id>(normalizedScalar * static_cast<vtkm::Float32>(ColorMapSize));
|
static_cast<vtkm::Id>(normalizedScalar * static_cast<vtkm::Float32>(ColorMapSize));
|
||||||
if (colorIndex < 0)
|
if (colorIndex < 0)
|
||||||
colorIndex = 0;
|
colorIndex = 0;
|
||||||
if (colorIndex > ColorMapSize)
|
if (colorIndex > ColorMapSize)
|
||||||
colorIndex = ColorMapSize;
|
colorIndex = ColorMapSize;
|
||||||
sampleColor = ColorMap.Get(colorIndex);
|
sampleColor = ColorMap.Get(colorIndex);
|
||||||
Locator.GetMinPoint(cell, bottomLeft);
|
|
||||||
tx = (sampleLocation[0] - bottomLeft[0]) * invSpacing[0];
|
|
||||||
ty = (sampleLocation[1] - bottomLeft[1]) * invSpacing[1];
|
|
||||||
tz = (sampleLocation[2] - bottomLeft[2]) * invSpacing[2];
|
|
||||||
newCell = false;
|
newCell = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,16 +504,18 @@ public:
|
|||||||
color[1] = color[1] + sampleColor[1] * alpha;
|
color[1] = color[1] + sampleColor[1] * alpha;
|
||||||
color[2] = color[2] + sampleColor[2] * alpha;
|
color[2] = color[2] + sampleColor[2] * alpha;
|
||||||
color[3] = alpha + color[3];
|
color[3] = alpha + color[3];
|
||||||
|
|
||||||
|
// terminate the ray early if it became completely opaque.
|
||||||
|
if (color[3] >= 1.f)
|
||||||
|
break;
|
||||||
|
|
||||||
//advance
|
//advance
|
||||||
distance += SampleDistance;
|
distance += SampleDistance;
|
||||||
sampleLocation = sampleLocation + SampleDistance * rayDir;
|
sampleLocation = sampleLocation + SampleDistance * rayDir;
|
||||||
|
|
||||||
if (color[3] >= 1.f)
|
parametric = (sampleLocation - bottomLeft) * invSpacing;
|
||||||
break;
|
|
||||||
tx = (sampleLocation[0] - bottomLeft[0]) * invSpacing[0];
|
|
||||||
ty = (sampleLocation[1] - bottomLeft[1]) * invSpacing[1];
|
|
||||||
tz = (sampleLocation[2] - bottomLeft[2]) * invSpacing[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
color[0] = vtkm::Min(color[0], 1.f);
|
color[0] = vtkm::Min(color[0], 1.f);
|
||||||
color[1] = vtkm::Min(color[1], 1.f);
|
color[1] = vtkm::Min(color[1], 1.f);
|
||||||
color[2] = vtkm::Min(color[2], 1.f);
|
color[2] = vtkm::Min(color[2], 1.f);
|
||||||
@ -663,7 +543,7 @@ class CalcRayStart : public vtkm::worklet::WorkletMapField
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
CalcRayStart(const vtkm::Bounds boundingBox)
|
explicit CalcRayStart(const vtkm::Bounds boundingBox)
|
||||||
{
|
{
|
||||||
Xmin = static_cast<vtkm::Float32>(boundingBox.X.Min);
|
Xmin = static_cast<vtkm::Float32>(boundingBox.X.Min);
|
||||||
Xmax = static_cast<vtkm::Float32>(boundingBox.X.Max);
|
Xmax = static_cast<vtkm::Float32>(boundingBox.X.Max);
|
||||||
@ -674,10 +554,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC
|
VTKM_EXEC
|
||||||
vtkm::Float32 rcp(vtkm::Float32 f) const { return 1.0f / f; }
|
static vtkm::Float32 rcp(vtkm::Float32 f) { return 1.0f / f; }
|
||||||
|
|
||||||
VTKM_EXEC
|
VTKM_EXEC
|
||||||
vtkm::Float32 rcp_safe(vtkm::Float32 f) const { return rcp((fabs(f) < 1e-8f) ? 1e-8f : f); }
|
static vtkm::Float32 rcp_safe(vtkm::Float32 f) { return rcp((fabs(f) < 1e-8f) ? 1e-8f : f); }
|
||||||
|
|
||||||
using ControlSignature = void(FieldIn, FieldOut, FieldInOut, FieldInOut, FieldIn);
|
using ControlSignature = void(FieldIn, FieldOut, FieldInOut, FieldInOut, FieldIn);
|
||||||
using ExecutionSignature = void(_1, _2, _3, _4, _5);
|
using ExecutionSignature = void(_1, _2, _3, _4, _5);
|
||||||
@ -688,12 +568,12 @@ public:
|
|||||||
vtkm::Float32& maxDistance,
|
vtkm::Float32& maxDistance,
|
||||||
const vtkm::Vec<Precision, 3>& rayOrigin) const
|
const vtkm::Vec<Precision, 3>& rayOrigin) const
|
||||||
{
|
{
|
||||||
vtkm::Float32 dirx = static_cast<vtkm::Float32>(rayDir[0]);
|
auto dirx = static_cast<vtkm::Float32>(rayDir[0]);
|
||||||
vtkm::Float32 diry = static_cast<vtkm::Float32>(rayDir[1]);
|
auto diry = static_cast<vtkm::Float32>(rayDir[1]);
|
||||||
vtkm::Float32 dirz = static_cast<vtkm::Float32>(rayDir[2]);
|
auto dirz = static_cast<vtkm::Float32>(rayDir[2]);
|
||||||
vtkm::Float32 origx = static_cast<vtkm::Float32>(rayOrigin[0]);
|
auto origx = static_cast<vtkm::Float32>(rayOrigin[0]);
|
||||||
vtkm::Float32 origy = static_cast<vtkm::Float32>(rayOrigin[1]);
|
auto origy = static_cast<vtkm::Float32>(rayOrigin[1]);
|
||||||
vtkm::Float32 origz = static_cast<vtkm::Float32>(rayOrigin[2]);
|
auto origz = static_cast<vtkm::Float32>(rayOrigin[2]);
|
||||||
|
|
||||||
vtkm::Float32 invDirx = rcp_safe(dirx);
|
vtkm::Float32 invDirx = rcp_safe(dirx);
|
||||||
vtkm::Float32 invDiry = rcp_safe(diry);
|
vtkm::Float32 invDiry = rcp_safe(diry);
|
||||||
@ -728,13 +608,6 @@ public:
|
|||||||
}
|
}
|
||||||
}; //class CalcRayStart
|
}; //class CalcRayStart
|
||||||
|
|
||||||
VolumeRendererStructured::VolumeRendererStructured()
|
|
||||||
{
|
|
||||||
IsSceneDirty = false;
|
|
||||||
IsUniformDataSet = true;
|
|
||||||
SampleDistance = -1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VolumeRendererStructured::SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec4f_32>& colorMap)
|
void VolumeRendererStructured::SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec4f_32>& colorMap)
|
||||||
{
|
{
|
||||||
ColorMap = colorMap;
|
ColorMap = colorMap;
|
||||||
@ -754,35 +627,15 @@ void VolumeRendererStructured::SetData(const vtkm::cont::CoordinateSystem& coord
|
|||||||
ScalarRange = scalarRange;
|
ScalarRange = scalarRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Precision>
|
|
||||||
struct VolumeRendererStructured::RenderFunctor
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
vtkm::rendering::raytracing::VolumeRendererStructured* Self;
|
|
||||||
vtkm::rendering::raytracing::Ray<Precision>& Rays;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
|
||||||
RenderFunctor(vtkm::rendering::raytracing::VolumeRendererStructured* self,
|
|
||||||
vtkm::rendering::raytracing::Ray<Precision>& rays)
|
|
||||||
: Self(self)
|
|
||||||
, Rays(rays)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Device>
|
|
||||||
VTKM_CONT bool operator()(Device)
|
|
||||||
{
|
|
||||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
|
||||||
|
|
||||||
this->Self->RenderOnDevice(this->Rays, Device());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void VolumeRendererStructured::Render(vtkm::rendering::raytracing::Ray<vtkm::Float32>& rays)
|
void VolumeRendererStructured::Render(vtkm::rendering::raytracing::Ray<vtkm::Float32>& rays)
|
||||||
{
|
{
|
||||||
RenderFunctor<vtkm::Float32> functor(this, rays);
|
auto functor = [&](auto device) {
|
||||||
|
using Device = typename std::decay_t<decltype(device)>;
|
||||||
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||||
|
|
||||||
|
this->RenderOnDevice(rays, device);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
vtkm::cont::TryExecute(functor);
|
vtkm::cont::TryExecute(functor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -799,6 +652,7 @@ void VolumeRendererStructured::RenderOnDevice(vtkm::rendering::raytracing::Ray<P
|
|||||||
{
|
{
|
||||||
vtkm::cont::Timer renderTimer{ Device() };
|
vtkm::cont::Timer renderTimer{ Device() };
|
||||||
renderTimer.Start();
|
renderTimer.Start();
|
||||||
|
|
||||||
Logger* logger = Logger::GetInstance();
|
Logger* logger = Logger::GetInstance();
|
||||||
logger->OpenLogEntry("volume_render_structured");
|
logger->OpenLogEntry("volume_render_structured");
|
||||||
logger->AddLogData("device", GetDeviceString(Device()));
|
logger->AddLogData("device", GetDeviceString(Device()));
|
||||||
@ -808,25 +662,26 @@ void VolumeRendererStructured::RenderOnDevice(vtkm::rendering::raytracing::Ray<P
|
|||||||
extent[1] = static_cast<vtkm::Float32>(this->SpatialExtent.Y.Length());
|
extent[1] = static_cast<vtkm::Float32>(this->SpatialExtent.Y.Length());
|
||||||
extent[2] = static_cast<vtkm::Float32>(this->SpatialExtent.Z.Length());
|
extent[2] = static_cast<vtkm::Float32>(this->SpatialExtent.Z.Length());
|
||||||
vtkm::Float32 mag_extent = vtkm::Magnitude(extent);
|
vtkm::Float32 mag_extent = vtkm::Magnitude(extent);
|
||||||
|
|
||||||
vtkm::Float32 meshEpsilon = mag_extent * 0.0001f;
|
vtkm::Float32 meshEpsilon = mag_extent * 0.0001f;
|
||||||
|
|
||||||
if (SampleDistance <= 0.f)
|
if (SampleDistance <= 0.f)
|
||||||
{
|
{
|
||||||
const vtkm::Float32 defaultNumberOfSamples = 200.f;
|
const vtkm::Float32 defaultNumberOfSamples = 200.f;
|
||||||
SampleDistance = mag_extent / defaultNumberOfSamples;
|
SampleDistance = mag_extent / defaultNumberOfSamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vtkm::cont::Invoker invoke;
|
||||||
|
|
||||||
vtkm::cont::Timer timer{ Device() };
|
vtkm::cont::Timer timer{ Device() };
|
||||||
timer.Start();
|
timer.Start();
|
||||||
vtkm::worklet::DispatcherMapField<CalcRayStart> calcRayStartDispatcher(
|
invoke(CalcRayStart{ this->SpatialExtent },
|
||||||
CalcRayStart(this->SpatialExtent));
|
rays.Dir,
|
||||||
calcRayStartDispatcher.SetDevice(Device());
|
rays.MinDistance,
|
||||||
calcRayStartDispatcher.Invoke(
|
rays.Distance,
|
||||||
rays.Dir, rays.MinDistance, rays.Distance, rays.MaxDistance, rays.Origin);
|
rays.MaxDistance,
|
||||||
|
rays.Origin);
|
||||||
vtkm::Float64 time = timer.GetElapsedTime();
|
vtkm::Float64 time = timer.GetElapsedTime();
|
||||||
logger->AddLogData("calc_ray_start", time);
|
logger->AddLogData("calc_ray_start", time);
|
||||||
|
|
||||||
timer.Start();
|
timer.Start();
|
||||||
|
|
||||||
const bool isSupportedField = ScalarField->IsCellField() || ScalarField->IsPointField();
|
const bool isSupportedField = ScalarField->IsCellField() || ScalarField->IsPointField();
|
||||||
@ -842,43 +697,45 @@ void VolumeRendererStructured::RenderOnDevice(vtkm::rendering::raytracing::Ray<P
|
|||||||
vtkm::cont::ArrayHandleUniformPointCoordinates vertices;
|
vtkm::cont::ArrayHandleUniformPointCoordinates vertices;
|
||||||
vertices =
|
vertices =
|
||||||
Coordinates.GetData().AsArrayHandle<vtkm::cont::ArrayHandleUniformPointCoordinates>();
|
Coordinates.GetData().AsArrayHandle<vtkm::cont::ArrayHandleUniformPointCoordinates>();
|
||||||
UniformLocator<Device> locator(vertices, Cellset, token);
|
vtkm::cont::CellLocatorUniformGrid uniLocator;
|
||||||
|
uniLocator.SetCellSet(this->Cellset);
|
||||||
|
uniLocator.SetCoordinates(this->Coordinates);
|
||||||
|
UniformLocatorAdapter<Device> locator(vertices, this->Cellset, uniLocator, token);
|
||||||
|
|
||||||
if (isAssocPoints)
|
if (isAssocPoints)
|
||||||
{
|
{
|
||||||
vtkm::worklet::DispatcherMapField<Sampler<Device, UniformLocator<Device>>> samplerDispatcher(
|
auto sampler = Sampler<Device, UniformLocatorAdapter<Device>>(ColorMap,
|
||||||
Sampler<Device, UniformLocator<Device>>(ColorMap,
|
vtkm::Float32(ScalarRange.Min),
|
||||||
vtkm::Float32(ScalarRange.Min),
|
vtkm::Float32(ScalarRange.Max),
|
||||||
vtkm::Float32(ScalarRange.Max),
|
SampleDistance,
|
||||||
SampleDistance,
|
locator,
|
||||||
locator,
|
meshEpsilon,
|
||||||
meshEpsilon,
|
token);
|
||||||
token));
|
invoke(sampler,
|
||||||
samplerDispatcher.SetDevice(Device());
|
rays.Dir,
|
||||||
samplerDispatcher.Invoke(
|
rays.Origin,
|
||||||
rays.Dir,
|
rays.MinDistance,
|
||||||
rays.Origin,
|
rays.MaxDistance,
|
||||||
rays.MinDistance,
|
rays.Buffers.at(0).Buffer,
|
||||||
rays.MaxDistance,
|
vtkm::rendering::raytracing::GetScalarFieldArray(*this->ScalarField));
|
||||||
rays.Buffers.at(0).Buffer,
|
|
||||||
vtkm::rendering::raytracing::GetScalarFieldArray(*this->ScalarField));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vtkm::worklet::DispatcherMapField<SamplerCellAssoc<Device, UniformLocator<Device>>>(
|
auto sampler =
|
||||||
SamplerCellAssoc<Device, UniformLocator<Device>>(ColorMap,
|
SamplerCellAssoc<Device, UniformLocatorAdapter<Device>>(ColorMap,
|
||||||
vtkm::Float32(ScalarRange.Min),
|
vtkm::Float32(ScalarRange.Min),
|
||||||
vtkm::Float32(ScalarRange.Max),
|
vtkm::Float32(ScalarRange.Max),
|
||||||
SampleDistance,
|
SampleDistance,
|
||||||
locator,
|
locator,
|
||||||
meshEpsilon,
|
meshEpsilon,
|
||||||
token))
|
token);
|
||||||
.Invoke(rays.Dir,
|
invoke(sampler,
|
||||||
rays.Origin,
|
rays.Dir,
|
||||||
rays.MinDistance,
|
rays.Origin,
|
||||||
rays.MaxDistance,
|
rays.MinDistance,
|
||||||
rays.Buffers.at(0).Buffer,
|
rays.MaxDistance,
|
||||||
vtkm::rendering::raytracing::GetScalarFieldArray(*this->ScalarField));
|
rays.Buffers.at(0).Buffer,
|
||||||
|
vtkm::rendering::raytracing::GetScalarFieldArray(*this->ScalarField));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -886,46 +743,46 @@ void VolumeRendererStructured::RenderOnDevice(vtkm::rendering::raytracing::Ray<P
|
|||||||
vtkm::cont::Token token;
|
vtkm::cont::Token token;
|
||||||
CartesianArrayHandle vertices;
|
CartesianArrayHandle vertices;
|
||||||
vertices = Coordinates.GetData().AsArrayHandle<CartesianArrayHandle>();
|
vertices = Coordinates.GetData().AsArrayHandle<CartesianArrayHandle>();
|
||||||
RectilinearLocator<Device> locator(vertices, Cellset, token);
|
vtkm::cont::CellLocatorRectilinearGrid rectLocator;
|
||||||
|
rectLocator.SetCellSet(this->Cellset);
|
||||||
|
rectLocator.SetCoordinates(this->Coordinates);
|
||||||
|
RectilinearLocatorAdapter<Device> locator(vertices, Cellset, rectLocator, token);
|
||||||
|
|
||||||
if (isAssocPoints)
|
if (isAssocPoints)
|
||||||
{
|
{
|
||||||
vtkm::worklet::DispatcherMapField<Sampler<Device, RectilinearLocator<Device>>>
|
auto sampler =
|
||||||
samplerDispatcher(
|
Sampler<Device, RectilinearLocatorAdapter<Device>>(ColorMap,
|
||||||
Sampler<Device, RectilinearLocator<Device>>(ColorMap,
|
vtkm::Float32(ScalarRange.Min),
|
||||||
vtkm::Float32(ScalarRange.Min),
|
vtkm::Float32(ScalarRange.Max),
|
||||||
vtkm::Float32(ScalarRange.Max),
|
SampleDistance,
|
||||||
SampleDistance,
|
locator,
|
||||||
locator,
|
meshEpsilon,
|
||||||
meshEpsilon,
|
token);
|
||||||
token));
|
invoke(sampler,
|
||||||
samplerDispatcher.SetDevice(Device());
|
rays.Dir,
|
||||||
samplerDispatcher.Invoke(
|
rays.Origin,
|
||||||
rays.Dir,
|
rays.MinDistance,
|
||||||
rays.Origin,
|
rays.MaxDistance,
|
||||||
rays.MinDistance,
|
rays.Buffers.at(0).Buffer,
|
||||||
rays.MaxDistance,
|
vtkm::rendering::raytracing::GetScalarFieldArray(*this->ScalarField));
|
||||||
rays.Buffers.at(0).Buffer,
|
|
||||||
vtkm::rendering::raytracing::GetScalarFieldArray(*this->ScalarField));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vtkm::worklet::DispatcherMapField<SamplerCellAssoc<Device, RectilinearLocator<Device>>>
|
auto sampler =
|
||||||
rectilinearLocatorDispatcher(
|
SamplerCellAssoc<Device, RectilinearLocatorAdapter<Device>>(ColorMap,
|
||||||
SamplerCellAssoc<Device, RectilinearLocator<Device>>(ColorMap,
|
vtkm::Float32(ScalarRange.Min),
|
||||||
vtkm::Float32(ScalarRange.Min),
|
vtkm::Float32(ScalarRange.Max),
|
||||||
vtkm::Float32(ScalarRange.Max),
|
SampleDistance,
|
||||||
SampleDistance,
|
locator,
|
||||||
locator,
|
meshEpsilon,
|
||||||
meshEpsilon,
|
token);
|
||||||
token));
|
invoke(sampler,
|
||||||
rectilinearLocatorDispatcher.SetDevice(Device());
|
rays.Dir,
|
||||||
rectilinearLocatorDispatcher.Invoke(
|
rays.Origin,
|
||||||
rays.Dir,
|
rays.MinDistance,
|
||||||
rays.Origin,
|
rays.MaxDistance,
|
||||||
rays.MinDistance,
|
rays.Buffers.at(0).Buffer,
|
||||||
rays.MaxDistance,
|
vtkm::rendering::raytracing::GetScalarFieldArray(*this->ScalarField));
|
||||||
rays.Buffers.at(0).Buffer,
|
|
||||||
vtkm::rendering::raytracing::GetScalarFieldArray(*this->ScalarField));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,19 +25,6 @@ namespace raytracing
|
|||||||
class VTKM_RENDERING_EXPORT VolumeRendererStructured
|
class VTKM_RENDERING_EXPORT VolumeRendererStructured
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using DefaultHandle = vtkm::cont::ArrayHandle<vtkm::FloatDefault>;
|
|
||||||
using CartesianArrayHandle =
|
|
||||||
vtkm::cont::ArrayHandleCartesianProduct<DefaultHandle, DefaultHandle, DefaultHandle>;
|
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
VolumeRendererStructured();
|
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
void EnableCompositeBackground();
|
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
void DisableCompositeBackground();
|
|
||||||
|
|
||||||
VTKM_CONT
|
VTKM_CONT
|
||||||
void SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec4f_32>& colorMap);
|
void SetColorMap(const vtkm::cont::ArrayHandle<vtkm::Vec4f_32>& colorMap);
|
||||||
|
|
||||||
@ -60,17 +47,15 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
template <typename Precision, typename Device>
|
template <typename Precision, typename Device>
|
||||||
VTKM_CONT void RenderOnDevice(vtkm::rendering::raytracing::Ray<Precision>& rays, Device);
|
VTKM_CONT void RenderOnDevice(vtkm::rendering::raytracing::Ray<Precision>& rays, Device);
|
||||||
template <typename Precision>
|
|
||||||
struct RenderFunctor;
|
|
||||||
|
|
||||||
bool IsSceneDirty;
|
bool IsSceneDirty = false;
|
||||||
bool IsUniformDataSet;
|
bool IsUniformDataSet = true;
|
||||||
vtkm::Bounds SpatialExtent;
|
vtkm::Bounds SpatialExtent;
|
||||||
vtkm::cont::CoordinateSystem Coordinates;
|
vtkm::cont::CoordinateSystem Coordinates;
|
||||||
vtkm::cont::CellSetStructured<3> Cellset;
|
vtkm::cont::CellSetStructured<3> Cellset;
|
||||||
const vtkm::cont::Field* ScalarField;
|
const vtkm::cont::Field* ScalarField;
|
||||||
vtkm::cont::ArrayHandle<vtkm::Vec4f_32> ColorMap;
|
vtkm::cont::ArrayHandle<vtkm::Vec4f_32> ColorMap;
|
||||||
vtkm::Float32 SampleDistance;
|
vtkm::Float32 SampleDistance = -1.f;
|
||||||
vtkm::Range ScalarRange;
|
vtkm::Range ScalarRange;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||||
#include <vtkm/cont/testing/Testing.h>
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
#include <vtkm/filter/field_conversion/CellAverage.h>
|
||||||
#include <vtkm/io/VTKDataSetReader.h>
|
#include <vtkm/io/VTKDataSetReader.h>
|
||||||
#include <vtkm/rendering/Actor.h>
|
#include <vtkm/rendering/Actor.h>
|
||||||
#include <vtkm/rendering/Canvas.h>
|
#include <vtkm/rendering/Canvas.h>
|
||||||
@ -18,12 +19,12 @@
|
|||||||
#include <vtkm/rendering/Scene.h>
|
#include <vtkm/rendering/Scene.h>
|
||||||
#include <vtkm/rendering/View3D.h>
|
#include <vtkm/rendering/View3D.h>
|
||||||
#include <vtkm/rendering/testing/RenderTest.h>
|
#include <vtkm/rendering/testing/RenderTest.h>
|
||||||
|
#include <vtkm/source/Tangle.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void TestRectilinear()
|
||||||
void RenderTests()
|
|
||||||
{
|
{
|
||||||
vtkm::cont::ColorTable colorTable = vtkm::cont::ColorTable::Preset::Inferno;
|
vtkm::cont::ColorTable colorTable = vtkm::cont::ColorTable::Preset::Inferno;
|
||||||
colorTable.AddPointAlpha(0.0, 0.01f);
|
colorTable.AddPointAlpha(0.0, 0.01f);
|
||||||
@ -56,6 +57,52 @@ void RenderTests()
|
|||||||
|
|
||||||
vtkm::rendering::testing::RenderTest(
|
vtkm::rendering::testing::RenderTest(
|
||||||
rectDS, "temp", "rendering/volume/rectilinear3D.png", options);
|
rectDS, "temp", "rendering/volume/rectilinear3D.png", options);
|
||||||
|
|
||||||
|
vtkm::filter::field_conversion::CellAverage cellAverage;
|
||||||
|
cellAverage.SetActiveField("temp");
|
||||||
|
cellAverage.SetOutputFieldName("temp_avg");
|
||||||
|
vtkm::cont::DataSet tempAvg = cellAverage.Execute(rectDS);
|
||||||
|
|
||||||
|
vtkm::rendering::testing::RenderTest(
|
||||||
|
tempAvg, "temp_avg", "rendering/volume/rectilinear3D_cell.png", options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestUniformGrid()
|
||||||
|
{
|
||||||
|
vtkm::cont::ColorTable colorTable = vtkm::cont::ColorTable::Preset::Inferno;
|
||||||
|
colorTable.AddPointAlpha(0.0, 0.2f);
|
||||||
|
colorTable.AddPointAlpha(0.2, 0.0f);
|
||||||
|
colorTable.AddPointAlpha(0.5, 0.0f);
|
||||||
|
|
||||||
|
vtkm::rendering::testing::RenderTestOptions options;
|
||||||
|
options.Mapper = vtkm::rendering::testing::MapperType::Volume;
|
||||||
|
options.AllowAnyDevice = false;
|
||||||
|
options.ColorTable = colorTable;
|
||||||
|
// Rendering of AxisAnnotation3D is sensitive on the type
|
||||||
|
// of FloatDefault, disable it before we know how to fix
|
||||||
|
// it properly.
|
||||||
|
options.EnableAnnotations = false;
|
||||||
|
|
||||||
|
vtkm::source::Tangle tangle;
|
||||||
|
tangle.SetPointDimensions({ 50, 50, 50 });
|
||||||
|
vtkm::cont::DataSet tangleData = tangle.Execute();
|
||||||
|
|
||||||
|
vtkm::rendering::testing::RenderTest(
|
||||||
|
tangleData, "tangle", "rendering/volume/uniform.png", options);
|
||||||
|
|
||||||
|
vtkm::filter::field_conversion::CellAverage cellAverage;
|
||||||
|
cellAverage.SetActiveField("tangle");
|
||||||
|
cellAverage.SetOutputFieldName("tangle_avg");
|
||||||
|
vtkm::cont::DataSet tangleAvg = cellAverage.Execute(tangleData);
|
||||||
|
|
||||||
|
vtkm::rendering::testing::RenderTest(
|
||||||
|
tangleAvg, "tangle_avg", "rendering/volume/uniform_cell.png", options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderTests()
|
||||||
|
{
|
||||||
|
TestRectilinear();
|
||||||
|
TestUniformGrid();
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
@ -8,3 +8,4 @@ DEPENDS
|
|||||||
vtkm_io
|
vtkm_io
|
||||||
TEST_DEPENDS
|
TEST_DEPENDS
|
||||||
vtkm_rendering_testing
|
vtkm_rendering_testing
|
||||||
|
vtkm_source
|
||||||
|
Loading…
Reference in New Issue
Block a user