mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 02:25:42 +00:00
Merge branch 'master' into extract-subset
This commit is contained in:
commit
5b651172cf
@ -31,6 +31,7 @@ add_subdirectory(hello_world)
|
||||
add_subdirectory(isosurface)
|
||||
add_subdirectory(multi_backend)
|
||||
add_subdirectory(streamline)
|
||||
add_subdirectory(tetrahedra)
|
||||
if(VTKm_ENABLE_RENDERING)
|
||||
add_subdirectory(rendering)
|
||||
endif()
|
||||
|
@ -47,11 +47,6 @@ if(VTKm_OpenGL_FOUND AND VTKm_GLUT_FOUND)
|
||||
target_link_libraries(TriangulateUniformGrid_SERIAL PRIVATE ${VTKm_LIBRARIES})
|
||||
target_compile_options(TriangulateUniformGrid_SERIAL PRIVATE ${VTKm_COMPILE_OPTIONS})
|
||||
|
||||
add_executable(TriangulateStructured_SERIAL TriangulateStructured.cxx)
|
||||
target_include_directories(TriangulateStructured_SERIAL PRIVATE ${VTKm_INCLUDE_DIRS})
|
||||
target_link_libraries(TriangulateStructured_SERIAL PRIVATE ${VTKm_LIBRARIES})
|
||||
target_compile_options(TriangulateStructured_SERIAL PRIVATE ${VTKm_COMPILE_OPTIONS})
|
||||
|
||||
if(VTKm_CUDA_FOUND)
|
||||
# Cuda compiles do not respect target_include_directories
|
||||
cuda_include_directories(${VTKm_INCLUDE_DIRS})
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
|
||||
#endif
|
||||
|
||||
#include <vtkm/worklet/TetrahedralizeExplicitGrid.h>
|
||||
#include <vtkm/filter/Tetrahedralize.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
@ -50,7 +50,6 @@ namespace {
|
||||
|
||||
// Takes input uniform grid and outputs unstructured grid of tets
|
||||
static vtkm::cont::DataSet outDataSet;
|
||||
vtkm::Id numberOfInPoints;
|
||||
|
||||
// Point location of vertices from a CastAndCall but needs a static cast eventually
|
||||
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3> > vertexArray;
|
||||
@ -206,7 +205,7 @@ void displayCall()
|
||||
|
||||
// Need the actual vertex points from a static cast of the dynamic array but can't get it right
|
||||
// So use cast and call on a functor that stores that dynamic array into static array we created
|
||||
vertexArray.Allocate(numberOfInPoints);
|
||||
vertexArray.Allocate(cellSet.GetNumberOfPoints());
|
||||
vtkm::cont::CastAndCall(outDataSet.GetCoordinateSystem(), GetVertexArray());
|
||||
|
||||
// Draw the five tetrahedra belonging to each hexadron
|
||||
@ -302,17 +301,11 @@ int main(int argc, char* argv[])
|
||||
vtkm::cont::CellSetExplicit<> inCellSet;
|
||||
inDataSet.GetCellSet(0).CopyTo(inCellSet);
|
||||
|
||||
numberOfInPoints = inCellSet.GetNumberOfPoints();
|
||||
|
||||
// Create the output dataset explicit cell set with same coordinate system
|
||||
vtkm::cont::CellSetSingleType<> cellSet("cells");
|
||||
outDataSet.AddCellSet(cellSet);
|
||||
outDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(0));
|
||||
|
||||
// Convert cells to tetrahedra
|
||||
vtkm::worklet::TetrahedralizeFilterExplicitGrid<DeviceAdapter>
|
||||
tetrahedralizeFilter(inDataSet, outDataSet);
|
||||
tetrahedralizeFilter.Run();
|
||||
vtkm::filter::Tetrahedralize tetrahedralize;
|
||||
vtkm::filter::ResultDataSet result = tetrahedralize.Execute(inDataSet);
|
||||
|
||||
outDataSet = result.GetDataSet();
|
||||
|
||||
// Render the output dataset of tets
|
||||
lastx = lasty = 0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
|
||||
#endif
|
||||
|
||||
#include <vtkm/worklet/TetrahedralizeUniformGrid.h>
|
||||
#include <vtkm/filter/Tetrahedralize.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
@ -48,10 +48,8 @@ typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
|
||||
// Default size of the example
|
||||
static vtkm::Id3 dims(4,4,4);
|
||||
static vtkm::Id cellsToDisplay = 64;
|
||||
static vtkm::Id numberOfInPoints;
|
||||
|
||||
// Takes input uniform grid and outputs unstructured grid of tets
|
||||
static vtkm::worklet::TetrahedralizeFilterUniformGrid<DeviceAdapter> *tetrahedralizeFilter;
|
||||
static vtkm::cont::DataSet tetDataSet;
|
||||
|
||||
// Point location of vertices from a CastAndCall but needs a static cast eventually
|
||||
@ -173,7 +171,7 @@ void displayCall()
|
||||
|
||||
// Need the actual vertex points from a static cast of the dynamic array but can't get it right
|
||||
// So use cast and call on a functor that stores that dynamic array into static array we created
|
||||
vertexArray.Allocate(numberOfInPoints);
|
||||
vertexArray.Allocate(cellSet.GetNumberOfPoints());
|
||||
vtkm::cont::CastAndCall(tetDataSet.GetCoordinateSystem(), GetVertexArray());
|
||||
|
||||
// Draw the five tetrahedra belonging to each hexadron
|
||||
@ -289,18 +287,10 @@ int main(int argc, char* argv[])
|
||||
// Create the input uniform cell set
|
||||
vtkm::cont::DataSet inDataSet = MakeTetrahedralizeTestDataSet(dims);
|
||||
|
||||
// Set number of cells and vertices in input dataset
|
||||
numberOfInPoints = (dims[0] + 1) * (dims[1] + 1) * (dims[2] + 1);
|
||||
vtkm::filter::Tetrahedralize tetrahedralize;
|
||||
vtkm::filter::ResultDataSet result = tetrahedralize.Execute(inDataSet);
|
||||
|
||||
// Create the output dataset explicit cell set with same coordinate system
|
||||
vtkm::cont::CellSetSingleType<> cellSet("cells");
|
||||
tetDataSet.AddCellSet(cellSet);
|
||||
tetDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(0));
|
||||
|
||||
// Convert uniform hexahedra to tetrahedra
|
||||
tetrahedralizeFilter = new vtkm::worklet::TetrahedralizeFilterUniformGrid<DeviceAdapter>
|
||||
(inDataSet, tetDataSet);
|
||||
tetrahedralizeFilter->Run();
|
||||
tetDataSet = result.GetDataSet();
|
||||
|
||||
// Render the output dataset of tets
|
||||
lastx = lasty = 0;
|
||||
@ -318,7 +308,6 @@ int main(int argc, char* argv[])
|
||||
glutMouseFunc(mouseCall);
|
||||
glutMainLoop();
|
||||
|
||||
delete tetrahedralizeFilter;
|
||||
tetDataSet.Clear();
|
||||
vertexArray.ReleaseResources();
|
||||
return 0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
|
||||
#endif
|
||||
|
||||
#include <vtkm/worklet/TetrahedralizeExplicitGrid.h>
|
||||
#include <vtkm/filter/Triangulate.h>
|
||||
#include <vtkm/cont/CellSetExplicit.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DataSetBuilderExplicit.h>
|
||||
@ -46,7 +46,6 @@ typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
|
||||
namespace {
|
||||
|
||||
// Takes input uniform grid and outputs unstructured grid of triangles
|
||||
static vtkm::worklet::TetrahedralizeFilterExplicitGrid<DeviceAdapter> *tetrahedralizeFilter;
|
||||
static vtkm::cont::DataSet outDataSet;
|
||||
static vtkm::Id numberOfInPoints;
|
||||
|
||||
@ -225,15 +224,10 @@ int main(int argc, char* argv[])
|
||||
|
||||
numberOfInPoints = inCellSet.GetNumberOfPoints();
|
||||
|
||||
// Create the output dataset explicit cell set with same coordinate system
|
||||
vtkm::cont::CellSetSingleType<> cellSet("cells");;
|
||||
outDataSet.AddCellSet(cellSet);
|
||||
outDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(0));
|
||||
|
||||
// Convert 2D explicit cells to triangles
|
||||
tetrahedralizeFilter = new vtkm::worklet::TetrahedralizeFilterExplicitGrid<DeviceAdapter>
|
||||
(inDataSet, outDataSet);
|
||||
tetrahedralizeFilter->Run();
|
||||
vtkm::filter::Triangulate triangulate;
|
||||
vtkm::filter::ResultDataSet result = triangulate.Execute(inDataSet);
|
||||
outDataSet = result.GetDataSet();
|
||||
|
||||
// Render the output dataset of tets
|
||||
glutInit(&argc, argv);
|
||||
@ -248,7 +242,6 @@ int main(int argc, char* argv[])
|
||||
glutDisplayFunc(displayCall);
|
||||
glutMainLoop();
|
||||
|
||||
delete tetrahedralizeFilter;
|
||||
outDataSet.Clear();
|
||||
vertexArray.ReleaseResources();
|
||||
return 0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
|
||||
#endif
|
||||
|
||||
#include <vtkm/worklet/TetrahedralizeUniformGrid.h>
|
||||
#include <vtkm/filter/Triangulate.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
@ -46,11 +46,9 @@ typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
|
||||
// Default size of the example
|
||||
static vtkm::Id2 dims(4,4);
|
||||
static vtkm::Id cellsToDisplay = 16;
|
||||
static vtkm::Id numberOfInPoints;
|
||||
|
||||
// Takes input uniform grid and outputs unstructured grid of triangles
|
||||
static vtkm::worklet::TetrahedralizeFilterUniformGrid<DeviceAdapter> *tetrahedralizeFilter;
|
||||
static vtkm::cont::DataSet tetDataSet;
|
||||
static vtkm::cont::DataSet triDataSet;
|
||||
|
||||
// Point location of vertices from a CastAndCall but needs a static cast eventually
|
||||
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3> > vertexArray;
|
||||
@ -68,7 +66,7 @@ vtkm::cont::DataSet MakeTriangulateTestDataSet(vtkm::Id2 dim)
|
||||
const vtkm::Vec<vtkm::Float32, 3> spacing = vtkm::make_Vec(
|
||||
1.0f/static_cast<vtkm::Float32>(dim[0]),
|
||||
1.0f/static_cast<vtkm::Float32>(dim[1]),
|
||||
1.0f/static_cast<vtkm::Float32>(dim[2]));
|
||||
0.0f);
|
||||
|
||||
// Generate coordinate system
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing);
|
||||
@ -131,12 +129,12 @@ void displayCall()
|
||||
|
||||
// Get the cellset, coordinate system and coordinate data
|
||||
vtkm::cont::CellSetSingleType<> cellSet;
|
||||
tetDataSet.GetCellSet(0).CopyTo(cellSet);
|
||||
triDataSet.GetCellSet(0).CopyTo(cellSet);
|
||||
|
||||
// Need the actual vertex points from a static cast of the dynamic array but can't get it right
|
||||
// So use cast and call on a functor that stores that dynamic array into static array we created
|
||||
vertexArray.Allocate(numberOfInPoints);
|
||||
vtkm::cont::CastAndCall(tetDataSet.GetCoordinateSystem(), GetVertexArray());
|
||||
vertexArray.Allocate(cellSet.GetNumberOfPoints());
|
||||
vtkm::cont::CastAndCall(triDataSet.GetCoordinateSystem(), GetVertexArray());
|
||||
|
||||
// Draw the two triangles belonging to each quad
|
||||
vtkm::Id triangle = 0;
|
||||
@ -178,7 +176,7 @@ void displayCall()
|
||||
glFlush();
|
||||
}
|
||||
|
||||
// Tetrahedralize and render uniform grid example
|
||||
// Triangulate and render uniform grid example
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::cout << "TrianguleUniformGrid Example" << std::endl;
|
||||
@ -195,20 +193,15 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
cellsToDisplay = atoi(argv[3]);
|
||||
}
|
||||
numberOfInPoints = (dims[0] + 1) * (dims[1] + 1);
|
||||
|
||||
// Create the input uniform cell set
|
||||
vtkm::cont::DataSet inDataSet = MakeTriangulateTestDataSet(dims);
|
||||
|
||||
// Create the output dataset explicit cell set with same coordinate system
|
||||
vtkm::cont::CellSetSingleType<> cellSet("cells");
|
||||
tetDataSet.AddCellSet(cellSet);
|
||||
tetDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(0));
|
||||
// Convert uniform quad to triangle
|
||||
vtkm::filter::Triangulate triangulate;
|
||||
vtkm::filter::ResultDataSet result = triangulate.Execute(inDataSet);
|
||||
|
||||
// Convert uniform hexahedra to tetrahedra
|
||||
tetrahedralizeFilter = new vtkm::worklet::TetrahedralizeFilterUniformGrid<DeviceAdapter>
|
||||
(inDataSet, tetDataSet);
|
||||
tetrahedralizeFilter->Run();
|
||||
triDataSet = result.GetDataSet();
|
||||
|
||||
// Render the output dataset of tets
|
||||
glutInit(&argc, argv);
|
||||
@ -223,8 +216,7 @@ int main(int argc, char* argv[])
|
||||
glutDisplayFunc(displayCall);
|
||||
glutMainLoop();
|
||||
|
||||
delete tetrahedralizeFilter;
|
||||
tetDataSet.Clear();
|
||||
triDataSet.Clear();
|
||||
vertexArray.ReleaseResources();
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ set(headers
|
||||
TransportTagKeyedValuesInOut.h
|
||||
TransportTagKeyedValuesOut.h
|
||||
TransportTagKeysIn.h
|
||||
TransportTagReducedValuesIn.h
|
||||
TransportTagTopologyFieldIn.h
|
||||
TransportTagWholeArrayIn.h
|
||||
TransportTagWholeArrayInOut.h
|
||||
|
@ -48,13 +48,11 @@ struct Transport<vtkm::cont::arg::TransportTagArrayIn, ContObjectType, Device>
|
||||
template<typename InputDomainType>
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(const ContObjectType &object,
|
||||
const InputDomainType &inputDomain,
|
||||
vtkm::Id) const
|
||||
const InputDomainType &vtkmNotUsed(inputDomain),
|
||||
vtkm::Id inputRange,
|
||||
vtkm::Id vtkmNotUsed(outputRange)) const
|
||||
{
|
||||
// This transport expects the input domain to be an array handle.
|
||||
VTKM_IS_ARRAY_HANDLE(InputDomainType);
|
||||
|
||||
if (object.GetNumberOfValues() != inputDomain.GetNumberOfValues())
|
||||
if (object.GetNumberOfValues() != inputRange)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Input array to worklet invocation the wrong size.");
|
||||
|
@ -51,13 +51,14 @@ struct Transport<vtkm::cont::arg::TransportTagArrayInOut, ContObjectType, Device
|
||||
template<typename InputDomainType>
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(ContObjectType object,
|
||||
const InputDomainType &,
|
||||
vtkm::Id size) const
|
||||
const InputDomainType &vtkmNotUsed(inputDomain),
|
||||
vtkm::Id vtkmNotUsed(inputRange),
|
||||
vtkm::Id outputRange) const
|
||||
{
|
||||
if (object.GetNumberOfValues() != size)
|
||||
if (object.GetNumberOfValues() != outputRange)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Input array to worklet invocation the wrong size.");
|
||||
"Input/output array to worklet invocation the wrong size.");
|
||||
}
|
||||
|
||||
return object.PrepareForInPlace(Device());
|
||||
|
@ -50,10 +50,11 @@ struct Transport<vtkm::cont::arg::TransportTagArrayOut, ContObjectType, Device>
|
||||
template<typename InputDomainType>
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(ContObjectType object,
|
||||
const InputDomainType &,
|
||||
vtkm::Id size) const
|
||||
const InputDomainType &vtkmNotUsed(inputDomain),
|
||||
vtkm::Id vtkmNotUsed(inputRange),
|
||||
vtkm::Id outputRange) const
|
||||
{
|
||||
return object.PrepareForOutput(size, Device());
|
||||
return object.PrepareForOutput(outputRange, Device());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -56,6 +56,7 @@ struct Transport<
|
||||
ExecObjectType operator()(
|
||||
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic> array,
|
||||
const InputDomainType &,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
// Note: we ignore the size of the domain because the randomly accessed
|
||||
|
@ -55,6 +55,7 @@ struct Transport<vtkm::cont::arg::TransportTagCellSetIn<FromTopology,ToTopology>
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(const ContObjectType &object,
|
||||
const InputDomainType &,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
return object.PrepareForInput(Device(),
|
||||
|
@ -54,6 +54,7 @@ struct Transport<vtkm::cont::arg::TransportTagExecObject,ContObjectType,Device>
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(const ContObjectType &object,
|
||||
const InputDomainType &,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
return object;
|
||||
|
@ -1,45 +0,0 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 2016 Sandia Corporation.
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_arg_TransportTagReducedValuesIn_h
|
||||
#define vtk_m_cont_arg_TransportTagReducedValuesIn_h
|
||||
|
||||
#include <vtkm/cont/arg/Transport.h>
|
||||
|
||||
namespace vtkm {
|
||||
namespace cont {
|
||||
namespace arg {
|
||||
|
||||
/// \brief \c Transport tag for input values in a reduce by key.
|
||||
///
|
||||
/// \c TransportTagReducedValuesIn is a tag used with the \c Transport class to
|
||||
/// transport \c ArrayHandle objects for input values that correspond to arrays
|
||||
/// of reduced values. The values are passed 1-to-1 to the worklet invocations.
|
||||
///
|
||||
struct TransportTagReducedValuesIn { };
|
||||
|
||||
// Specialization of Transport class for TransportTagReducedValuesIn is
|
||||
// implemented in vtkm/worklet/Keys.h. That class is not accessible from here
|
||||
// due to VTK-m package dependencies.
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //vtk_m_cont_arg_TransportTagReducedValuesIn_h
|
@ -88,6 +88,7 @@ struct Transport<
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(const ContObjectType &object,
|
||||
const vtkm::cont::CellSet &inputDomain,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
if (object.GetNumberOfValues() !=
|
||||
|
@ -60,6 +60,7 @@ struct Transport<
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(ContObjectType array,
|
||||
const InputDomainType &,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
// Note: we ignore the size of the domain because the randomly accessed
|
||||
|
@ -62,6 +62,7 @@ struct Transport<
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(ContObjectType array,
|
||||
const InputDomainType &,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
// Note: we ignore the size of the domain because the randomly accessed
|
||||
|
@ -62,6 +62,7 @@ struct Transport<
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(ContObjectType array,
|
||||
const InputDomainType &,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
// Note: we ignore the size of the domain because the randomly accessed
|
||||
|
@ -70,7 +70,7 @@ struct TryArrayInType
|
||||
transport;
|
||||
|
||||
TestKernel<PortalType> kernel;
|
||||
kernel.Portal = transport(handle, handle, ARRAY_SIZE);
|
||||
kernel.Portal = transport(handle, handle, ARRAY_SIZE, ARRAY_SIZE);
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ struct TryArrayInOutType
|
||||
transport;
|
||||
|
||||
TestKernel<PortalType> kernel;
|
||||
kernel.Portal = transport(handle, handle, ARRAY_SIZE);
|
||||
kernel.Portal = transport(handle, handle, ARRAY_SIZE, ARRAY_SIZE);
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);
|
||||
|
||||
|
@ -64,6 +64,7 @@ struct TryArrayOutType
|
||||
TestKernel<PortalType> kernel;
|
||||
kernel.Portal = transport(handle,
|
||||
vtkm::cont::ArrayHandleIndex(ARRAY_SIZE),
|
||||
ARRAY_SIZE,
|
||||
ARRAY_SIZE);
|
||||
|
||||
VTKM_TEST_ASSERT(handle.GetNumberOfValues() == ARRAY_SIZE,
|
||||
|
@ -84,7 +84,7 @@ void TransportWholeCellSetIn(Device)
|
||||
transport;
|
||||
|
||||
TestKernel<ExecObjectType> kernel;
|
||||
kernel.CellSet = transport(contObject, nullptr, 1);
|
||||
kernel.CellSet = transport(contObject, nullptr, 1, 1);
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, 1);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ void TryExecObjectTransport(Device)
|
||||
transport;
|
||||
|
||||
TestKernel kernel;
|
||||
kernel.Object = transport(contObject, nullptr, 1);
|
||||
kernel.Object = transport(contObject, nullptr, 1, 1);
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, 1);
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ struct TryWholeArrayType
|
||||
|
||||
std::cout << "Check Transport WholeArrayOut" << std::endl;
|
||||
TestOutKernel<typename OutTransportType::ExecObjectType> outKernel;
|
||||
outKernel.Portal = OutTransportType()(array, nullptr, -1);
|
||||
outKernel.Portal = OutTransportType()(array, nullptr, -1, -1);
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(outKernel, ARRAY_SIZE);
|
||||
|
||||
@ -139,13 +139,13 @@ struct TryWholeArrayType
|
||||
|
||||
std::cout << "Check Transport WholeArrayIn" << std::endl;
|
||||
TestInKernel<typename InTransportType::ExecObjectType> inKernel;
|
||||
inKernel.Portal = InTransportType()(array, nullptr, -1);
|
||||
inKernel.Portal = InTransportType()(array, nullptr, -1, -1);
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(inKernel, ARRAY_SIZE);
|
||||
|
||||
std::cout << "Check Transport WholeArrayInOut" << std::endl;
|
||||
TestInOutKernel<typename InOutTransportType::ExecObjectType> inOutKernel;
|
||||
inOutKernel.Portal = InOutTransportType()(array, nullptr, -1);
|
||||
inOutKernel.Portal = InOutTransportType()(array, nullptr, -1, -1);
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(inOutKernel, ARRAY_SIZE);
|
||||
|
||||
@ -180,7 +180,7 @@ struct TryAtomicArrayType
|
||||
|
||||
std::cout << "Check Transport AtomicArray" << std::endl;
|
||||
TestAtomicKernel<typename TransportType::ExecObjectType>
|
||||
kernel(TransportType()(array, nullptr, -1));
|
||||
kernel(TransportType()(array, nullptr, -1, -1));
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);
|
||||
|
||||
|
@ -18,9 +18,33 @@
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/worklet/ScatterCounting.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template<typename DeviceAdapter>
|
||||
class DeduceCellSet
|
||||
{
|
||||
mutable vtkm::worklet::Tetrahedralize Worklet;
|
||||
vtkm::cont::CellSetSingleType<> &OutCellSet;
|
||||
|
||||
public:
|
||||
DeduceCellSet(vtkm::worklet::Tetrahedralize worklet,
|
||||
vtkm::cont::CellSetSingleType<>& outCellSet) :
|
||||
Worklet(worklet),
|
||||
OutCellSet(outCellSet)
|
||||
{}
|
||||
|
||||
template<typename CellSetType>
|
||||
void operator()(const CellSetType& cellset ) const
|
||||
{
|
||||
this->OutCellSet = Worklet.Run(cellset, DeviceAdapter());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace vtkm {
|
||||
namespace filter {
|
||||
|
||||
@ -38,27 +62,17 @@ template<typename DerivedPolicy,
|
||||
inline VTKM_CONT
|
||||
vtkm::filter::ResultDataSet Tetrahedralize::DoExecute(
|
||||
const vtkm::cont::DataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&,
|
||||
const DeviceAdapter& device)
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
const DeviceAdapter&)
|
||||
{
|
||||
typedef vtkm::cont::CellSetStructured<3> CellSetStructuredType;
|
||||
typedef vtkm::cont::CellSetExplicit<> CellSetExplicitType;
|
||||
|
||||
const vtkm::cont::DynamicCellSet& cells =
|
||||
input.GetCellSet(this->GetActiveCellSetIndex());
|
||||
|
||||
vtkm::cont::CellSetSingleType<> outCellSet;
|
||||
DeduceCellSet<DeviceAdapter> tetrahedralize(this->Worklet, outCellSet);
|
||||
|
||||
if (cells.IsType<CellSetStructuredType>())
|
||||
{
|
||||
outCellSet = this->Worklet.Run(cells.Cast<CellSetStructuredType>(),
|
||||
device);
|
||||
}
|
||||
else
|
||||
{
|
||||
outCellSet = this->Worklet.Run(cells.Cast<CellSetExplicitType>(),
|
||||
device);
|
||||
}
|
||||
vtkm::cont::CastAndCall(vtkm::filter::ApplyPolicy(cells, policy),
|
||||
tetrahedralize);
|
||||
|
||||
// create the output dataset
|
||||
vtkm::cont::DataSet output;
|
||||
|
@ -18,9 +18,33 @@
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/worklet/ScatterCounting.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template<typename DeviceAdapter>
|
||||
class DeduceCellSet
|
||||
{
|
||||
mutable vtkm::worklet::Triangulate Worklet;
|
||||
vtkm::cont::CellSetSingleType<> &OutCellSet;
|
||||
|
||||
public:
|
||||
DeduceCellSet(vtkm::worklet::Triangulate worklet,
|
||||
vtkm::cont::CellSetSingleType<>& outCellSet) :
|
||||
Worklet(worklet),
|
||||
OutCellSet(outCellSet)
|
||||
{}
|
||||
|
||||
template<typename CellSetType>
|
||||
void operator()(const CellSetType& cellset ) const
|
||||
{
|
||||
this->OutCellSet = Worklet.Run(cellset, DeviceAdapter());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace vtkm {
|
||||
namespace filter {
|
||||
|
||||
@ -37,28 +61,19 @@ template<typename DerivedPolicy,
|
||||
typename DeviceAdapter>
|
||||
inline VTKM_CONT
|
||||
vtkm::filter::ResultDataSet Triangulate::DoExecute(
|
||||
const vtkm::cont::DataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&,
|
||||
const DeviceAdapter& device)
|
||||
const vtkm::cont::DataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
|
||||
const DeviceAdapter&)
|
||||
{
|
||||
typedef vtkm::cont::CellSetStructured<2> CellSetStructuredType;
|
||||
typedef vtkm::cont::CellSetExplicit<> CellSetExplicitType;
|
||||
|
||||
const vtkm::cont::DynamicCellSet& cells =
|
||||
input.GetCellSet(this->GetActiveCellSetIndex());
|
||||
|
||||
vtkm::cont::CellSetSingleType<> outCellSet;
|
||||
DeduceCellSet<DeviceAdapter> triangulate(this->Worklet, outCellSet);
|
||||
|
||||
vtkm::cont::CastAndCall(vtkm::filter::ApplyPolicy(cells, policy),
|
||||
triangulate);
|
||||
|
||||
if (cells.IsType<CellSetStructuredType>())
|
||||
{
|
||||
outCellSet = this->Worklet.Run(cells.Cast<CellSetStructuredType>(),
|
||||
device);
|
||||
}
|
||||
else
|
||||
{
|
||||
outCellSet = this->Worklet.Run(cells.Cast<CellSetExplicitType>(),
|
||||
device);
|
||||
}
|
||||
|
||||
// create the output dataset
|
||||
vtkm::cont::DataSet output;
|
||||
|
@ -364,7 +364,7 @@ void TestMarchingCubesCustomPolicy()
|
||||
|
||||
|
||||
vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem();
|
||||
VTKM_TEST_ASSERT(coords.GetData().GetNumberOfValues() == 414,
|
||||
VTKM_TEST_ASSERT(coords.GetData().GetNumberOfValues() == (414*4),
|
||||
"Should have some coordinates");
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,15 @@ public:
|
||||
"Wrong result for Tetrahedralize");
|
||||
VTKM_TEST_ASSERT(test_equal(output.GetField("pointvar").GetData().GetNumberOfValues(), 18),
|
||||
"Wrong number of points for Tetrahedralize");
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> outData =
|
||||
output.GetField("cellvar").GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32> >();
|
||||
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(5) == 100.2f, "Wrong cell field data");
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(6) == 100.2f, "Wrong cell field data");
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(7) == 100.2f, "Wrong cell field data");
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(8) == 100.2f, "Wrong cell field data");
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(9) == 100.2f, "Wrong cell field data");
|
||||
}
|
||||
|
||||
void TestExplicit() const
|
||||
@ -68,6 +77,15 @@ public:
|
||||
"Wrong result for Tetrahedralize");
|
||||
VTKM_TEST_ASSERT(test_equal(output.GetField("pointvar").GetData().GetNumberOfValues(), 11),
|
||||
"Wrong number of points for Tetrahedralize");
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> outData =
|
||||
output.GetField("cellvar").GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32> >();
|
||||
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(5) == 110.f, "Wrong cell field data");
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(6) == 110.f, "Wrong cell field data");
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(8) == 130.5f, "Wrong cell field data");
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(9) == 130.5f, "Wrong cell field data");
|
||||
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(10) == 130.5f, "Wrong cell field data");
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
|
@ -274,6 +274,7 @@ private:
|
||||
ExecObjectParameters execObjectParameters =
|
||||
parameters.StaticTransformCont(TransportFunctorType(
|
||||
invocation.GetInputDomain(),
|
||||
inputRange,
|
||||
outputRange));
|
||||
|
||||
// Get the arrays used for scattering input to output.
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <vtkm/cont/arg/TransportTagKeyedValuesInOut.h>
|
||||
#include <vtkm/cont/arg/TransportTagKeyedValuesOut.h>
|
||||
#include <vtkm/cont/arg/TransportTagKeysIn.h>
|
||||
#include <vtkm/cont/arg/TransportTagReducedValuesIn.h>
|
||||
#include <vtkm/cont/arg/TypeCheckTagKeys.h>
|
||||
|
||||
#include <vtkm/BinaryOperators.h>
|
||||
@ -152,6 +151,12 @@ public:
|
||||
(this->Counts == other.Counts));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
bool operator!=(const vtkm::worklet::Keys<KeyType> &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
KeyArrayHandleType UniqueKeys;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> SortedValuesMap;
|
||||
@ -221,9 +226,14 @@ struct Transport<vtkm::cont::arg::TransportTagKeysIn,
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(const ContObjectType &object,
|
||||
const ContObjectType &inputDomain,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
VTKM_ASSERT(object == inputDomain);
|
||||
if (object != inputDomain)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"A Keys object must be the input domain.");
|
||||
}
|
||||
|
||||
return object.PrepareForInput(Device());
|
||||
}
|
||||
@ -234,6 +244,7 @@ struct Transport<vtkm::cont::arg::TransportTagKeysIn,
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(const ContObjectType &,
|
||||
const InputDomainType &,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const = delete;
|
||||
};
|
||||
|
||||
@ -258,9 +269,13 @@ struct Transport<
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(const ContObjectType &object,
|
||||
const vtkm::worklet::Keys<KeyType> &keys,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
VTKM_ASSERT(object.GetNumberOfValues() == keys.GetNumberOfValues());
|
||||
if (object.GetNumberOfValues() != keys.GetNumberOfValues())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Input values array is wrong size.");
|
||||
}
|
||||
|
||||
PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
|
||||
GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
|
||||
@ -294,9 +309,14 @@ struct Transport<
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(ContObjectType object,
|
||||
const vtkm::worklet::Keys<KeyType> &keys,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
VTKM_ASSERT(object.GetNumberOfValues() == keys.GetNumberOfValues());
|
||||
if (object.GetNumberOfValues() != keys.GetNumberOfValues())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Input/output values array is wrong size.");
|
||||
}
|
||||
|
||||
PermutedArrayType permutedArray(keys.GetSortedValuesMap(), object);
|
||||
GroupedArrayType groupedArray(permutedArray, keys.GetOffsets());
|
||||
@ -330,6 +350,7 @@ struct Transport<
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(ContObjectType object,
|
||||
const vtkm::worklet::Keys<KeyType> &keys,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
// The PrepareForOutput for ArrayHandleGroupVecVariable and
|
||||
@ -348,31 +369,6 @@ struct Transport<
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ContObjectType, typename Device>
|
||||
struct Transport<
|
||||
vtkm::cont::arg::TransportTagReducedValuesIn, ContObjectType, Device>
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(ContObjectType);
|
||||
|
||||
typedef typename ContObjectType::template ExecutionTypes<Device>::PortalConst
|
||||
ExecObjectType;
|
||||
|
||||
template<typename KeyType>
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(const ContObjectType &object,
|
||||
const vtkm::worklet::Keys<KeyType> &inputDomain,
|
||||
vtkm::Id) const
|
||||
{
|
||||
if (object.GetNumberOfValues() != inputDomain.GetInputRange())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Input array to worklet invocation the wrong size.");
|
||||
}
|
||||
|
||||
return object.PrepareForInput(Device());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::arg
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define vtk_m_worklet_MarchingCubes_h
|
||||
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
#include <vtkm/BinaryPredicates.h>
|
||||
|
||||
#include <vtkm/exec/CellDerivative.h>
|
||||
#include <vtkm/exec/ParametricCoordinates.h>
|
||||
@ -431,12 +432,77 @@ struct FirstValueSame
|
||||
{
|
||||
template<typename T, typename U>
|
||||
VTKM_EXEC_CONT bool operator()(const vtkm::Pair<T,U>& a,
|
||||
const vtkm::Pair<T,U>& b) const
|
||||
const vtkm::Pair<T,U>& b) const
|
||||
{
|
||||
return (a.first == b.first);
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
struct MultiContourLess
|
||||
{
|
||||
template<typename T>
|
||||
VTKM_EXEC_CONT bool operator()(const T& a, const T& b) const
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
VTKM_EXEC_CONT bool operator()(const vtkm::Pair<T,U>& a,
|
||||
const vtkm::Pair<T,U>& b) const
|
||||
{
|
||||
return (a.first < b.first) || (!(b.first < a.first) && (a.second < b.second));
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
VTKM_EXEC_CONT bool operator()(const vtkm::internal::ArrayPortalValueReference<T>& a,
|
||||
const U& b) const
|
||||
{
|
||||
U&& t = static_cast<U>(a);
|
||||
return t < b;
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template<typename KeyType, typename KeyStorage,
|
||||
typename ValueType, typename ValueStorage,
|
||||
typename DeviceAdapterTag>
|
||||
vtkm::cont::ArrayHandle<KeyType, KeyStorage>
|
||||
MergeDuplicates(const vtkm::cont::ArrayHandle<KeyType, KeyStorage>& input_keys,
|
||||
vtkm::cont::ArrayHandle<ValueType, ValueStorage> values,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
DeviceAdapterTag)
|
||||
{
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>;
|
||||
|
||||
//1. Copy the input keys as we need both a sorted & unique version and
|
||||
// the original version to
|
||||
vtkm::cont::ArrayHandle<KeyType, KeyStorage> keys;
|
||||
Algorithm::Copy(input_keys, keys);
|
||||
|
||||
//2. Sort by key, making duplicate ids be adjacent so they are eligable
|
||||
// to be removed by unique
|
||||
Algorithm::SortByKey(keys, values, marchingcubes::MultiContourLess());
|
||||
|
||||
//3. lastly we need to do a unique by key, but since vtkm doesn't
|
||||
// offer that feature, we use a zip handle.
|
||||
// We use a custom comparison operator as we only want to compare
|
||||
// the keys
|
||||
auto zipped_kv = vtkm::cont::make_ArrayHandleZip(keys, values);
|
||||
Algorithm::Unique( zipped_kv, marchingcubes::FirstValueSame());
|
||||
|
||||
//4. LowerBounds generates the output cell connections. It does this by
|
||||
// finding for each interpolationId where it would be inserted in the
|
||||
// sorted & unique subset, which generates an index value aka the lookup
|
||||
// value.
|
||||
//
|
||||
Algorithm::LowerBounds(keys, input_keys, connectivity, marchingcubes::MultiContourLess());
|
||||
|
||||
//5. We need to return the sorted-unique keys as the caller will need
|
||||
// to hold onto it for interpolation of other fields
|
||||
return keys;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// \brief Compute the isosurface for a uniform grid data set
|
||||
@ -570,19 +636,19 @@ vtkm::cont::CellSetSingleType< >
|
||||
using vtkm::worklet::marchingcubes::ClassifyCell;
|
||||
|
||||
// Setup the Dispatcher Typedefs
|
||||
typedef typename vtkm::worklet::DispatcherMapTopology<
|
||||
ClassifyCell<ValueType>,
|
||||
DeviceAdapter
|
||||
> ClassifyDispatcher;
|
||||
using ClassifyDispatcher = typename vtkm::worklet::DispatcherMapTopology<
|
||||
ClassifyCell<ValueType>,
|
||||
DeviceAdapter
|
||||
>;
|
||||
|
||||
typedef typename vtkm::worklet::DispatcherMapTopology<
|
||||
EdgeWeightGenerate<ValueType,
|
||||
NormalType,
|
||||
StorageTagNormals,
|
||||
DeviceAdapter
|
||||
>,
|
||||
DeviceAdapter
|
||||
> GenerateDispatcher;
|
||||
using GenerateDispatcher = typename vtkm::worklet::DispatcherMapTopology<
|
||||
EdgeWeightGenerate<ValueType,
|
||||
NormalType,
|
||||
StorageTagNormals,
|
||||
DeviceAdapter
|
||||
>,
|
||||
DeviceAdapter
|
||||
>;
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> isoValuesHandle =
|
||||
vtkm::cont::make_ArrayHandle(isovalues, numIsoValues);
|
||||
@ -632,106 +698,84 @@ vtkm::cont::CellSetSingleType< >
|
||||
coordinateSystem
|
||||
);
|
||||
|
||||
if(numIsoValues <= 1)
|
||||
if(numIsoValues <= 1 || !this->MergeDuplicatePoints)
|
||||
{ //release memory early that we are not going to need again
|
||||
contourIds.ReleaseResources();
|
||||
}
|
||||
|
||||
//Now that we have the edge interpolation finished we can generate the
|
||||
//following:
|
||||
//1. Coordinates ( with option to do point merging )
|
||||
// Now that we have the edge interpolation finished we can generate the
|
||||
// coordinates, connectivity and resolve duplicate points.
|
||||
// Given that normals, and point merging are optional it generates the
|
||||
// following permutations that we need to support
|
||||
//
|
||||
//[0] 1 iso-contour
|
||||
//[1] 1 iso-contour + point merging
|
||||
//[2] 1 iso-contour + point merging + normals
|
||||
//[3] 1 iso-contour + normals
|
||||
//[4] 2+ iso-contour
|
||||
//[5] 2+ iso-contour + point merging
|
||||
//[6] 2+ iso-contour + point merging + normals
|
||||
//[7] 2+ iso-contour + normals
|
||||
//
|
||||
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> Algorithm;
|
||||
|
||||
// [0], [3], [4], and [7] are easy to implement as they require zero logic
|
||||
// other than simple connectivity generation. The challenge is the other
|
||||
// 4 options
|
||||
vtkm::cont::DataSet output;
|
||||
vtkm::cont::ArrayHandle< vtkm::Id > connectivity;
|
||||
|
||||
typedef vtkm::cont::ArrayHandle< vtkm::Id2 > Id2HandleType;
|
||||
typedef vtkm::cont::ArrayHandle< vtkm::UInt8 > ContourIdHandleType;
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::FloatDefault> WeightHandleType;
|
||||
if(this->MergeDuplicatePoints)
|
||||
{
|
||||
//Do merge duplicate points we need to do the following:
|
||||
//1. Copy the interpolation Ids
|
||||
Id2HandleType uniqueIds;
|
||||
Algorithm::Copy(this->InterpolationIds, uniqueIds);
|
||||
|
||||
if(withNormals)
|
||||
// In all the below cases you will notice that only interpolation ids
|
||||
// are updated. That is because MergeDuplicates will internally update
|
||||
// the InterpolationWeights and normals arrays to be the correct for the
|
||||
// output. But for InterpolationIds we need to do it manually once done
|
||||
if(withNormals && numIsoValues == 1)
|
||||
{
|
||||
typedef vtkm::cont::ArrayHandle< vtkm::Vec<CoordinateType,3>, StorageTagNormals > NormalHandlType;
|
||||
typedef vtkm::cont::ArrayHandleZip<WeightHandleType, NormalHandlType> KeyType;
|
||||
KeyType keys = vtkm::cont::make_ArrayHandleZip(this->InterpolationWeights, normals);
|
||||
|
||||
//2. now we need to do a sort by key, making duplicate ids be adjacent
|
||||
if(numIsoValues > 1)
|
||||
{
|
||||
vtkm::cont::ArrayHandleZip<
|
||||
Id2HandleType, ContourIdHandleType> uniqueIdsWithContourId =
|
||||
vtkm::cont::make_ArrayHandleZip(uniqueIds, contourIds);
|
||||
Algorithm::SortByKey(uniqueIdsWithContourId, keys);
|
||||
}
|
||||
else
|
||||
{
|
||||
Algorithm::SortByKey(uniqueIds, keys);
|
||||
}
|
||||
|
||||
//3. lastly we need to do a unique by key, but since vtkm doesn't
|
||||
// offer that feature, we use a zip handle.
|
||||
// We need to use a custom comparison operator as we only want to compare
|
||||
// the id2 which is the first entry in the zip pair
|
||||
vtkm::cont::ArrayHandleZip<Id2HandleType, KeyType> zipped =
|
||||
vtkm::cont::make_ArrayHandleZip(uniqueIds,keys);
|
||||
Algorithm::Unique( zipped, marchingcubes::FirstValueSame());
|
||||
auto&& result = marchingcubes::MergeDuplicates(
|
||||
this->InterpolationIds, //keys
|
||||
vtkm::cont::make_ArrayHandleZip(this->InterpolationWeights, normals), //values
|
||||
connectivity,
|
||||
DeviceAdapter() );
|
||||
this->InterpolationIds = result;
|
||||
}
|
||||
else
|
||||
else if(withNormals && numIsoValues > 1)
|
||||
{
|
||||
//2. now we need to do a sort by key, making duplicate ids be adjacent
|
||||
if(numIsoValues > 1)
|
||||
{
|
||||
vtkm::cont::ArrayHandleZip<
|
||||
Id2HandleType, ContourIdHandleType> uniqueIdsWithContourId =
|
||||
vtkm::cont::make_ArrayHandleZip(uniqueIds, contourIds);
|
||||
Algorithm::SortByKey(uniqueIdsWithContourId, this->InterpolationWeights);
|
||||
}
|
||||
else
|
||||
{
|
||||
Algorithm::SortByKey(uniqueIds, this->InterpolationWeights);
|
||||
}
|
||||
|
||||
|
||||
//3. lastly we need to do a unique by key, but since vtkm doesn't
|
||||
// offer that feature, we use a zip handle.
|
||||
// We need to use a custom comparison operator as we only want to compare
|
||||
// the id2 which is the first entry in the zip pair
|
||||
vtkm::cont::ArrayHandleZip<Id2HandleType, WeightHandleType> zipped =
|
||||
vtkm::cont::make_ArrayHandleZip(uniqueIds, this->InterpolationWeights);
|
||||
Algorithm::Unique( zipped, marchingcubes::FirstValueSame());
|
||||
auto&& result = marchingcubes::MergeDuplicates(
|
||||
vtkm::cont::make_ArrayHandleZip(contourIds, this->InterpolationIds), //keys
|
||||
vtkm::cont::make_ArrayHandleZip(this->InterpolationWeights, normals), //values
|
||||
connectivity,
|
||||
DeviceAdapter() );
|
||||
this->InterpolationIds = result.GetStorage().GetSecondArray();
|
||||
}
|
||||
else if(!withNormals && numIsoValues == 1)
|
||||
{
|
||||
auto&& result = marchingcubes::MergeDuplicates(
|
||||
this->InterpolationIds, //keys
|
||||
this->InterpolationWeights, //values
|
||||
connectivity,
|
||||
DeviceAdapter() );
|
||||
this->InterpolationIds = result;
|
||||
}
|
||||
else if(!withNormals && numIsoValues >= 1)
|
||||
{
|
||||
auto&& result = marchingcubes::MergeDuplicates(
|
||||
vtkm::cont::make_ArrayHandleZip(contourIds, this->InterpolationIds), //keys
|
||||
this->InterpolationWeights, //values
|
||||
connectivity,
|
||||
DeviceAdapter() );
|
||||
this->InterpolationIds = result.GetStorage().GetSecondArray();
|
||||
}
|
||||
|
||||
//4.
|
||||
//LowerBounds generates the output cell connections. It does this by
|
||||
//finding for each interpolationId where it would be inserted in the
|
||||
//sorted & unique subset, which generates an index value aka the lookup
|
||||
//value.
|
||||
//
|
||||
Algorithm::LowerBounds(uniqueIds, this->InterpolationIds, connectivity);
|
||||
|
||||
//5.
|
||||
//We re-assign the shortened version of unique ids back into the
|
||||
//member variable so that 'DoMapField' will work properly
|
||||
this->InterpolationIds = uniqueIds;
|
||||
}
|
||||
else
|
||||
{
|
||||
//when we don't merge points, the connectivity array can be represented
|
||||
//by a counting array. The danger of doing it this way is that the output
|
||||
//type is unknown. That is why we use a CellSetSingleType with explicit
|
||||
//storage;
|
||||
//type is unknown. That is why we copy it into an explicit array
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
|
||||
vtkm::cont::ArrayHandleIndex temp(this->InterpolationIds.GetNumberOfValues());
|
||||
Algorithm::Copy(temp, connectivity);
|
||||
}
|
||||
|
||||
|
||||
//generate the vertices's
|
||||
ApplyToField applyToField;
|
||||
vtkm::worklet::DispatcherMapField<ApplyToField,
|
||||
|
@ -63,8 +63,9 @@ public:
|
||||
Tetrahedralize() : OutCellsPerCell() {}
|
||||
|
||||
// Tetrahedralize explicit data set, save number of tetra cells per input
|
||||
template <typename DeviceAdapter>
|
||||
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetExplicit<> &cellSet,
|
||||
template <typename CellSetType,
|
||||
typename DeviceAdapter>
|
||||
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
|
||||
const DeviceAdapter&)
|
||||
{
|
||||
TetrahedralizeExplicit<DeviceAdapter> worklet;
|
||||
@ -80,6 +81,14 @@ public:
|
||||
return worklet.Run(cellSet, this->OutCellsPerCell);
|
||||
}
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2>&,
|
||||
const DeviceAdapter&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("CellSetStructured<2> can't be tetrahedralized");
|
||||
return vtkm::cont::CellSetSingleType<>();
|
||||
}
|
||||
|
||||
// Using the saved input to output cells, expand cell data
|
||||
template <typename T,
|
||||
typename StorageType,
|
||||
|
@ -63,8 +63,9 @@ public:
|
||||
Triangulate() : OutCellsPerCell() {}
|
||||
|
||||
// Triangulate explicit data set, save number of triangulated cells per input
|
||||
template <typename DeviceAdapter>
|
||||
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetExplicit<> &cellSet,
|
||||
template <typename CellSetType,
|
||||
typename DeviceAdapter>
|
||||
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
|
||||
const DeviceAdapter&)
|
||||
{
|
||||
TriangulateExplicit<DeviceAdapter> worklet;
|
||||
@ -80,6 +81,14 @@ public:
|
||||
return worklet.Run(cellSet, this->OutCellsPerCell);
|
||||
}
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3>&,
|
||||
const DeviceAdapter&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("CellSetStructured<3> can't be triangulated");
|
||||
return vtkm::cont::CellSetSingleType<>();
|
||||
}
|
||||
|
||||
// Using the saved input to output cells, expand cell data
|
||||
template <typename T,
|
||||
typename StorageType,
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <vtkm/cont/arg/TransportTagKeyedValuesInOut.h>
|
||||
#include <vtkm/cont/arg/TransportTagKeyedValuesOut.h>
|
||||
#include <vtkm/cont/arg/TransportTagKeysIn.h>
|
||||
#include <vtkm/cont/arg/TransportTagReducedValuesIn.h>
|
||||
#include <vtkm/cont/arg/TypeCheckTagArray.h>
|
||||
#include <vtkm/cont/arg/TypeCheckTagKeys.h>
|
||||
|
||||
@ -127,7 +126,7 @@ public:
|
||||
struct ReducedValuesIn : vtkm::cont::arg::ControlSignatureTagBase
|
||||
{
|
||||
using TypeCheckTag = vtkm::cont::arg::TypeCheckTagArray<TypeList>;
|
||||
using TransportTag = vtkm::cont::arg::TransportTagReducedValuesIn;
|
||||
using TransportTag = vtkm::cont::arg::TransportTagArrayIn;
|
||||
using FetchTag = vtkm::exec::arg::FetchTagArrayDirectIn;
|
||||
};
|
||||
|
||||
|
@ -215,30 +215,41 @@ struct DispatcherBaseTransportInvokeTypes
|
||||
typedef typename ControlSignatureTag::TransportTag TransportTag;
|
||||
};
|
||||
|
||||
VTKM_CONT
|
||||
inline
|
||||
vtkm::Id FlatRange(vtkm::Id range)
|
||||
{
|
||||
return range;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
inline
|
||||
vtkm::Id FlatRange(const vtkm::Id3 &range)
|
||||
{
|
||||
return range[0]*range[1]*range[2];
|
||||
}
|
||||
|
||||
// A functor used in a StaticCast of a FunctionInterface to transport arguments
|
||||
// from the control environment to the execution environment.
|
||||
template<typename ControlInterface, typename InputDomainType, typename Device>
|
||||
struct DispatcherBaseTransportFunctor
|
||||
{
|
||||
const InputDomainType &InputDomain; // Warning: this is a reference
|
||||
vtkm::Id OutputSize;
|
||||
|
||||
VTKM_CONT
|
||||
DispatcherBaseTransportFunctor(const InputDomainType &inputDomain,
|
||||
vtkm::Id outputSize)
|
||||
: InputDomain(inputDomain),
|
||||
OutputSize(outputSize)
|
||||
{ }
|
||||
vtkm::Id InputRange;
|
||||
vtkm::Id OutputRange;
|
||||
|
||||
// TODO: We need to think harder about how scheduling on 3D arrays works.
|
||||
// Chances are we need to allow the transport for each argument to manage
|
||||
// 3D indices (for example, allocate a 3D array instead of a 1D array).
|
||||
// But for now, just treat all transports as 1D arrays.
|
||||
template<typename InputRangeType, typename OutputRangeType>
|
||||
VTKM_CONT
|
||||
DispatcherBaseTransportFunctor(const InputDomainType &inputDomain,
|
||||
vtkm::Id3 dimensions)
|
||||
const InputRangeType &inputRange,
|
||||
const OutputRangeType &outputRange)
|
||||
: InputDomain(inputDomain),
|
||||
OutputSize(dimensions[0]*dimensions[1]*dimensions[2])
|
||||
InputRange(FlatRange(inputRange)),
|
||||
OutputRange(FlatRange(outputRange))
|
||||
{ }
|
||||
|
||||
|
||||
@ -257,7 +268,10 @@ struct DispatcherBaseTransportFunctor
|
||||
{
|
||||
using TransportTag = typename DispatcherBaseTransportInvokeTypes<ControlInterface, Index>::TransportTag;
|
||||
vtkm::cont::arg::Transport<TransportTag,ControlParameter,Device> transport;
|
||||
return transport(invokeData, this->InputDomain, this->OutputSize);
|
||||
return transport(invokeData,
|
||||
this->InputDomain,
|
||||
this->InputRange,
|
||||
this->OutputRange);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -491,6 +505,7 @@ private:
|
||||
ExecObjectParameters execObjectParameters =
|
||||
parameters.StaticTransformCont(TransportFunctorType(
|
||||
invocation.GetInputDomain(),
|
||||
inputRange,
|
||||
outputRange));
|
||||
|
||||
// Get the arrays used for scattering input to output.
|
||||
|
@ -78,9 +78,14 @@ struct Transport<TestTransportTag, vtkm::Id *, Device>
|
||||
typedef TestExecObject ExecObjectType;
|
||||
|
||||
VTKM_CONT
|
||||
ExecObjectType operator()(vtkm::Id *contData, vtkm::Id *, vtkm::Id size) const
|
||||
ExecObjectType operator()(vtkm::Id *contData,
|
||||
vtkm::Id *,
|
||||
vtkm::Id inputRange,
|
||||
vtkm::Id outputRange) const
|
||||
{
|
||||
VTKM_TEST_ASSERT(size == ARRAY_SIZE,
|
||||
VTKM_TEST_ASSERT(inputRange == ARRAY_SIZE,
|
||||
"Got unexpected size in test transport.");
|
||||
VTKM_TEST_ASSERT(outputRange == ARRAY_SIZE,
|
||||
"Got unexpected size in test transport.");
|
||||
return ExecObjectType(contData);
|
||||
}
|
||||
|
@ -127,10 +127,10 @@ public:
|
||||
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
|
||||
|
||||
// Input topology
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> inShapes =
|
||||
auto inShapes =
|
||||
cellSet.GetShapesArray(vtkm::TopologyElementTagPoint(),
|
||||
vtkm::TopologyElementTagCell());
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> inNumIndices =
|
||||
auto inNumIndices =
|
||||
cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(),
|
||||
vtkm::TopologyElementTagCell());
|
||||
|
||||
|
@ -129,10 +129,10 @@ public:
|
||||
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
|
||||
|
||||
// Input topology
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> inShapes =
|
||||
auto inShapes =
|
||||
cellSet.GetShapesArray(vtkm::TopologyElementTagPoint(),
|
||||
vtkm::TopologyElementTagCell());
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> inNumIndices =
|
||||
auto inNumIndices =
|
||||
cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(),
|
||||
vtkm::TopologyElementTagCell());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user