mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Connected component for triangle mesh
This commit is contained in:
parent
8be1a71ada
commit
2e88f4220a
@ -25,6 +25,7 @@ set(CMAKE_PREFIX_PATH ${VTKm_BINARY_DIR}/${VTKm_INSTALL_CONFIG_DIR})
|
||||
|
||||
add_subdirectory(clipping)
|
||||
add_subdirectory(contour_tree)
|
||||
add_subdirectory(connected_component_labeling)
|
||||
add_subdirectory(cosmotools)
|
||||
add_subdirectory(demo)
|
||||
add_subdirectory(dynamic_dispatcher)
|
||||
|
153
examples/connected_component_labeling/CCL.cpp
Normal file
153
examples/connected_component_labeling/CCL.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/DataSetBuilderUniform.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
|
||||
#include <vtkm/filter/FilterDataSet.h>
|
||||
#include <vtkm/worklet/DispatcherPointNeighborhood.h>
|
||||
#include <vtkm/worklet/WorkletPointNeighborhood.h>
|
||||
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
//#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
|
||||
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
|
||||
//#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
|
||||
void populate(std::vector<vtkm::Float32>& pixels,
|
||||
std::vector<vtkm::Id>& components,
|
||||
vtkm::UInt32 width,
|
||||
vtkm::UInt32 height)
|
||||
{
|
||||
for (auto& pixel : pixels) {
|
||||
pixel = 0.0f;
|
||||
}
|
||||
|
||||
for (int i = 6; i <= 8; i++) {
|
||||
pixels[i] = 1.0f;
|
||||
}
|
||||
|
||||
for (int i = 16; i <= 18; i++) {
|
||||
pixels[i] = 1.0f;
|
||||
}
|
||||
|
||||
for (int i = 0; i < width*height; ++i) {
|
||||
components[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
struct UpdateComponent : public vtkm::worklet::WorkletPointNeighborhood3x3x3
|
||||
{
|
||||
typedef void ControlSignature(FieldInNeighborhood<Scalar> pixel,
|
||||
CellSetIn,
|
||||
FieldInNeighborhood<IdType> prevComponent,
|
||||
FieldOut<IdType> component);
|
||||
|
||||
typedef void ExecutionSignature(_1, _3, _4);
|
||||
|
||||
//verify input domain can be something other than first parameter
|
||||
typedef _2 InputDomain;
|
||||
|
||||
template <typename FieldIn, typename FieldIn1, typename FieldOut>
|
||||
VTKM_EXEC void operator()(const vtkm::exec::arg::Neighborhood<1, FieldIn>& pixel,
|
||||
const vtkm::exec::arg::Neighborhood<1, FieldIn1>& prevComponent,
|
||||
FieldOut& component) const
|
||||
//FieldIn1& component) const
|
||||
{
|
||||
//vtkm::UInt8 color =
|
||||
std::cout << "pixel: " << pixel.Get(0, 0, 0)
|
||||
<< ", component: " << prevComponent.Get(0, 0, 0)
|
||||
<< std::endl;
|
||||
|
||||
vtkm::Float32 color = pixel.Get(0, 0, 0);
|
||||
if (color == pixel.Get(-1, 0, 0)) {
|
||||
component = prevComponent.Get(-1, 0, 0);
|
||||
} else if (color == pixel.Get(0, -1, 0)) {
|
||||
component = prevComponent.Get(0, -1, 0);
|
||||
} else {
|
||||
component = prevComponent.Get(0, 0, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct FindRoot : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
typedef void ControlSignature(FieldIn<IdType>,
|
||||
WholeArrayInOut<IdType> component);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
typedef _1 Inputdomain;
|
||||
|
||||
template <typename FieldIn, typename FieldOut>
|
||||
VTKM_EXEC void operator()(const FieldIn& id, FieldOut& component) const {
|
||||
//while (id != component.Get(id)) {
|
||||
// if (id != component.Get(id)) {
|
||||
// std::cout << "id: " << id << ", component: " << component.Get(id) << std::endl;
|
||||
// component.Set(id, this->operator()(component.Get(id), component));
|
||||
// }
|
||||
vtkm::Id parent = component.Get(id);
|
||||
while (parent != component.Get(parent)) {
|
||||
parent = component.Get(parent);
|
||||
component.Set(id, parent);
|
||||
|
||||
std::cout << "id: " << id << ", component: " << component.Get(id) << std::endl;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
vtkm::cont::DataSetBuilderUniform builder;
|
||||
vtkm::cont::DataSet data = builder.Create(vtkm::Id2(5, 5));
|
||||
std::vector<vtkm::Float32> pixels(5*5);
|
||||
std::vector<vtkm::Id> components(5*5);
|
||||
populate(pixels, components, 5, 5);
|
||||
vtkm::cont::Field pixelField("pixels", vtkm::cont::Field::ASSOC_POINTS, pixels);
|
||||
data.AddField(pixelField);
|
||||
|
||||
vtkm::cont::Field componentField("components", vtkm::cont::Field::ASSOC_POINTS, components);
|
||||
data.AddField(componentField);
|
||||
|
||||
vtkm::worklet::DispatcherPointNeighborhood<UpdateComponent> dispatcher;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> output;
|
||||
dispatcher.Invoke(data.GetField("pixels"),
|
||||
data.GetCellSet(),
|
||||
data.GetField("components"),
|
||||
output);
|
||||
|
||||
for (int i = 0; i < output.GetNumberOfValues(); i++) {
|
||||
std::cout << output.GetPortalConstControl().Get(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<FindRoot> findRootDispatcher;
|
||||
findRootDispatcher.Invoke(data.GetField("components"), output);
|
||||
for (int i = 0; i < output.GetNumberOfValues(); i++) {
|
||||
std::cout << output.GetPortalConstControl().Get(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
7
examples/connected_component_labeling/CMakeLists.txt
Normal file
7
examples/connected_component_labeling/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
find_package(VTKm REQUIRED QUIET
|
||||
OPTIONAL_COMPONENTS Serial #CUDA TBB OpenGL GLUT
|
||||
)
|
||||
|
||||
add_executable(CCL CCL.cpp)
|
||||
target_link_libraries(CCL PRIVATE ${VTKm_LIBRARIES})
|
||||
target_compile_options(CCL PRIVATE ${VTKm_COMPILE_OPTIONS})
|
@ -20,7 +20,7 @@
|
||||
##
|
||||
##=============================================================================
|
||||
|
||||
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
||||
#cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
||||
project(GameOfLife CXX)
|
||||
|
||||
#Find the VTK-m package
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
static vtkm::Id3 dims(256, 256, 256);
|
||||
static vtkm::Id3 dims(4, 4, 4);
|
||||
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> verticesArray, normalsArray;
|
||||
static vtkm::cont::ArrayHandle<vtkm::Float32> scalarsArray;
|
||||
static Quaternion qrot;
|
||||
@ -245,7 +245,7 @@ int main(int argc, char* argv[])
|
||||
vtkm::filter::MarchingCubes filter;
|
||||
filter.SetGenerateNormals(true);
|
||||
filter.SetMergeDuplicatePoints(false);
|
||||
filter.SetIsoValue(0, 0.5);
|
||||
filter.SetIsoValue(0, 0.1);
|
||||
vtkm::filter::Result result = filter.Execute(dataSet, dataSet.GetField("nodevar"));
|
||||
|
||||
filter.MapFieldOntoOutput(result, dataSet.GetField("nodevar"));
|
||||
|
@ -763,6 +763,28 @@ public:
|
||||
DerivedAlgorithm::Sort(zipHandle, internal::KeyCompare<T, U, BinaryCompare>(binary_compare));
|
||||
}
|
||||
|
||||
template <typename T, typename U, class StorageT, class StorageU, class BinaryFunctor>
|
||||
VTKM_CONT static void Transform(vtkm::cont::ArrayHandle<T, StorageT>& input1,
|
||||
vtkm::cont::ArrayHandle<T, StorageT>& input2,
|
||||
vtkm::cont::ArrayHandle<U, StorageU>& output,
|
||||
BinaryFunctor binaryFunctor)
|
||||
{
|
||||
vtkm::Id numValues = vtkm::Min(input1.GetNumberOfValues(), input2.GetNumberOfValues());
|
||||
if (numValues <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto input1Portal = input1.PrepareForInput(DeviceAdapterTag());
|
||||
auto input2Portal = input2.PrepareForInput(DeviceAdapterTag());
|
||||
auto outputPortal = output.PrepareForOutput(numValues, DeviceAdapterTag());
|
||||
|
||||
BinaryTransformKernel<decltype(input1Portal), decltype(outputPortal), BinaryFunctor>
|
||||
binaryKernel(input1Portal, input2Portal, outputPortal, binaryFunctor);
|
||||
DerivedAlgorithm::Schedule(binaryKernel, numValues);
|
||||
}
|
||||
|
||||
//};
|
||||
//--------------------------------------------------------------------------
|
||||
// Unique
|
||||
template <typename T, class Storage>
|
||||
|
@ -881,6 +881,37 @@ struct ScanKernel : vtkm::exec::FunctorBase
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InPortalType, typename OutPortalType, typename BinaryFunctor>
|
||||
struct BinaryTransformKernel : vtkm::exec::FunctorBase
|
||||
{
|
||||
using ValueType = typename InPortalType::ValueType;
|
||||
|
||||
InPortalType InPortal1;
|
||||
InPortalType InPortal2;
|
||||
OutPortalType OutPortal;
|
||||
BinaryFunctor BinaryOperator;
|
||||
|
||||
VTKM_CONT
|
||||
BinaryTransformKernel(const InPortalType& inPortal1,
|
||||
const InPortalType& inPortal2,
|
||||
const OutPortalType& outPortal,
|
||||
BinaryFunctor binaryOperator)
|
||||
: InPortal1(inPortal1)
|
||||
, InPortal2(inPortal2)
|
||||
, OutPortal(outPortal)
|
||||
, BinaryOperator(binaryOperator)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC
|
||||
void operator()(vtkm::Id index) const
|
||||
{
|
||||
this->OutPortal.Set(
|
||||
index, this->BinaryOperator(this->InPortal1.Get(index), this->InPortal2.Get(index)));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::internal
|
||||
|
218
vtkm/worklet/connectivities/CellSetDualGraph.h
Normal file
218
vtkm/worklet/connectivities/CellSetDualGraph.h
Normal file
@ -0,0 +1,218 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_worklet_CellSetDualGraph_h
|
||||
#define vtk_m_worklet_CellSetDualGraph_h
|
||||
|
||||
#include <vtkm/cont/CellSetSingleType.h>
|
||||
|
||||
struct EdgeCount : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
typedef void ControlSignature(CellSetIn, FieldOutCell<> numEdgesInCell);
|
||||
typedef _2 ExecutionSignature(CellShape, PointCount);
|
||||
using InputDomain = _1;
|
||||
|
||||
template <typename CellShapeTag>
|
||||
VTKM_EXEC vtkm::IdComponent operator()(CellShapeTag cellShape, vtkm::IdComponent pointCount) const
|
||||
{
|
||||
return vtkm::exec::CellEdgeNumberOfEdges(pointCount, cellShape, *this);
|
||||
}
|
||||
};
|
||||
|
||||
struct EdgeExtract : public vtkm::worklet::WorkletMapPointToCell
|
||||
{
|
||||
typedef void ControlSignature(CellSetIn, FieldOutCell<> cellIndices, FieldOutCell<> edgeIndices);
|
||||
|
||||
typedef void ExecutionSignature(CellShape, InputIndex, PointIndices, VisitIndex, _2, _3);
|
||||
using InputDomain = _1;
|
||||
|
||||
using ScatterType = vtkm::worklet::ScatterCounting;
|
||||
VTKM_CONT ScatterType GetScatter() const { return this->Scatter; }
|
||||
|
||||
VTKM_CONT EdgeExtract(const ScatterType& scatter)
|
||||
: Scatter(scatter)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename CellShapeTag,
|
||||
typename CellIndexType,
|
||||
typename PointIndexVecType,
|
||||
typename EdgeIndexVecType>
|
||||
VTKM_EXEC void operator()(CellShapeTag cellShape,
|
||||
CellIndexType cellIndex,
|
||||
PointIndexVecType& pointIndices,
|
||||
vtkm::IdComponent visitIndex,
|
||||
CellIndexType& cellIndexOut,
|
||||
EdgeIndexVecType& edgeIndices) const
|
||||
{
|
||||
cellIndexOut = cellIndex;
|
||||
edgeIndices = vtkm::exec::CellEdgeCanonicalId(
|
||||
pointIndices.GetNumberOfComponents(), visitIndex, cellShape, pointIndices, *this);
|
||||
};
|
||||
|
||||
private:
|
||||
ScatterType Scatter;
|
||||
};
|
||||
|
||||
struct CellToCellConnectivity : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
typedef void ControlSignature(FieldIn<> index,
|
||||
WholeArrayIn<> cells,
|
||||
WholeArrayOut<> from,
|
||||
WholeArrayOut<> to);
|
||||
|
||||
typedef void ExecutionSignature(_1, InputIndex, _2, _3, _4);
|
||||
using InputDomain = _1;
|
||||
|
||||
template <typename ConnectivityPortalType, typename CellIdPortalType>
|
||||
VTKM_EXEC void operator()(vtkm::Id offset,
|
||||
vtkm::Id index,
|
||||
const CellIdPortalType& cells,
|
||||
ConnectivityPortalType& from,
|
||||
ConnectivityPortalType& to) const
|
||||
{
|
||||
from.Set(index * 2, cells.Get(offset));
|
||||
to.Set(index * 2, cells.Get(offset + 1));
|
||||
from.Set(index * 2 + 1, cells.Get(offset + 1));
|
||||
to.Set(index * 2 + 1, cells.Get(offset));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
class CellSetDualGraph
|
||||
{
|
||||
public:
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
|
||||
|
||||
struct degree2
|
||||
{
|
||||
VTKM_EXEC
|
||||
bool operator()(vtkm::Id degree) const { return degree == 2; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void EdgeToCellConnectivity(const vtkm::cont::CellSetSingleType<T>& cellSet,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& cellIds,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id2>& cellEdges) const
|
||||
{
|
||||
// Get number of edges for each cell and use it as scatter count.
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> numEdgesPerCell;
|
||||
vtkm::worklet::DispatcherMapTopology<EdgeCount> edgesPerCellDisp;
|
||||
edgesPerCellDisp.Invoke(cellSet, numEdgesPerCell);
|
||||
|
||||
// Get uncompress Cell to Edge mapping
|
||||
vtkm::worklet::ScatterCounting scatter{ numEdgesPerCell, DeviceAdapter() };
|
||||
vtkm::worklet::DispatcherMapTopology<EdgeExtract> edgeExtractDisp{ scatter };
|
||||
edgeExtractDisp.Invoke(cellSet, cellIds, cellEdges);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Run(vtkm::cont::CellSetSingleType<T>& cellSet,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& numIndicesArray,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& indexOffsetArray,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>& connectivityArray) const
|
||||
{
|
||||
// calculate the uncompressed Edge to Cell connectivity from Point to Cell connectivity
|
||||
// in the CellSet
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellIds;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id2> cellEdges;
|
||||
EdgeToCellConnectivity(cellSet, cellIds, cellEdges);
|
||||
// for (int i = 0; i < cellIds.GetNumberOfValues(); i++) {
|
||||
// std::cout << cellIds.GetPortalConstControl().Get(i) << " "
|
||||
// << cellEdges.GetPortalConstControl().Get(i) << std::endl;
|
||||
// }
|
||||
|
||||
// sort cell ids by cell edges, this groups cells by cell edges
|
||||
Algorithm::SortByKey(cellEdges, cellIds);
|
||||
// for (int i = 0; i < cellIds.GetNumberOfValues(); i++) {
|
||||
// std::cout << cellEdges.GetPortalConstControl().Get(i) << " "
|
||||
// << cellIds.GetPortalConstControl().Get(i) << std::endl;
|
||||
// }
|
||||
|
||||
// count how many times an edge is shared by cells.
|
||||
vtkm::cont::ArrayHandle<vtkm::Id2> uniqueEdges;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> uniqueEdgeDegree;
|
||||
Algorithm::ReduceByKey(
|
||||
cellEdges,
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id>(1, cellEdges.GetNumberOfValues()),
|
||||
uniqueEdges,
|
||||
uniqueEdgeDegree,
|
||||
vtkm::Add());
|
||||
// for (int i = 0; i < uniqueEdges.GetNumberOfValues(); i++) {
|
||||
// std::cout << uniqueEdges.GetPortalConstControl().Get(i) << " "
|
||||
// << uniqueEdgeDegree.GetPortalConstControl().Get(i) << std::endl;
|
||||
// }
|
||||
|
||||
// Extract edges shared by two cells
|
||||
vtkm::cont::ArrayHandle<vtkm::Id2> sharedEdges;
|
||||
Algorithm::CopyIf(uniqueEdges, uniqueEdgeDegree, sharedEdges, degree2());
|
||||
// for (int i = 0; i < sharedEdges.GetNumberOfValues(); i++) {
|
||||
// std::cout << "graph edge: " << sharedEdges.GetPortalConstControl().Get(i)
|
||||
// << std::endl;
|
||||
// }
|
||||
|
||||
// find shared edges within all the edges.
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> lb;
|
||||
Algorithm::LowerBounds(cellEdges, sharedEdges, lb);
|
||||
// for (int i = 0; i < lb.GetNumberOfValues(); i++) {
|
||||
// std::cout << "lower bound: " << lb.GetPortalConstControl().Get(i)
|
||||
// << std::endl;
|
||||
// }
|
||||
|
||||
// take each shared edge and the cells to create 2 edges of the dual graph
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> connFrom;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> connTo;
|
||||
connFrom.Allocate(sharedEdges.GetNumberOfValues() * 2);
|
||||
connTo.Allocate(sharedEdges.GetNumberOfValues() * 2);
|
||||
vtkm::worklet::DispatcherMapField<CellToCellConnectivity> c2cDisp;
|
||||
c2cDisp.Invoke(lb, cellIds, connFrom, connTo);
|
||||
|
||||
// for (int i = 0; i < connFrom.GetNumberOfValues(); i++) {
|
||||
// std::cout << "from cell: " << connFrom.GetPortalConstControl().Get(i)
|
||||
// << ", to cell: " << connTo.GetPortalConstControl().Get(i)
|
||||
// << std::endl;
|
||||
// }
|
||||
|
||||
// Turn
|
||||
Algorithm::SortByKey(connFrom, connTo);
|
||||
// for (int i = 0; i < connFrom.GetNumberOfValues(); i++) {
|
||||
// std::cout << "from cell: " << connFrom.GetPortalConstControl().Get(i)
|
||||
// << ", to cell: " << connTo.GetPortalConstControl().Get(i)
|
||||
// << std::endl;
|
||||
// }
|
||||
Algorithm::Copy(connTo, connectivityArray);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> dualGraphVertices;
|
||||
Algorithm::ReduceByKey(
|
||||
connFrom,
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id>(1, connFrom.GetNumberOfValues()),
|
||||
dualGraphVertices,
|
||||
numIndicesArray,
|
||||
vtkm::Add());
|
||||
// for (int i = 0; i < dualGraphVertices.GetNumberOfValues(); i++) {
|
||||
// std::cout << "dual graph vertex: " << dualGraphVertices.GetPortalConstControl().Get(i)
|
||||
// << ", degree: " << numIndicesArray.GetPortalConstControl().Get(i)
|
||||
// << std::endl;
|
||||
// }
|
||||
|
||||
Algorithm::ScanExclusive(numIndicesArray, indexOffsetArray);
|
||||
}
|
||||
};
|
||||
#endif //vtk_m_worklet_CellSetDualGraph_h
|
145
vtkm/worklet/connectivities/GraphConnectivity.h
Normal file
145
vtkm/worklet/connectivities/GraphConnectivity.h
Normal file
@ -0,0 +1,145 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_worklet_connectivity_graph_connectivity_h
|
||||
#define vtk_m_worklet_connectivity_graph_connectivity_h
|
||||
|
||||
#include <vtkm/worklet/connectivities/CellSetDualGraph.h>
|
||||
#include <vtkm/worklet/connectivities/InnerJoin.h>
|
||||
|
||||
class Graft : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<IdType> index,
|
||||
FieldIn<IdType> start,
|
||||
FieldIn<IdType> degree,
|
||||
WholeArrayIn<IdType> ids,
|
||||
WholeArrayInOut<IdType> comp);
|
||||
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5);
|
||||
typedef _1 InputDomain;
|
||||
|
||||
// TODO: Use Scatter?
|
||||
template <typename InPortalType, typename InOutPortalType>
|
||||
VTKM_EXEC void operator()(vtkm::Id index,
|
||||
vtkm::Id start,
|
||||
vtkm::Id degree,
|
||||
const InPortalType& conn,
|
||||
InOutPortalType& comp) const
|
||||
{
|
||||
for (vtkm::Id offset = start; offset < start + degree; offset++)
|
||||
{
|
||||
vtkm::Id neighbor = conn.Get(offset);
|
||||
if ((comp.Get(index) == comp.Get(comp.Get(index))) && (comp.Get(neighbor) < comp.Get(index)))
|
||||
{
|
||||
comp.Set(comp.Get(index), comp.Get(neighbor));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PointerJumping : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<IdType> index, WholeArrayInOut<IdType> comp);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
typedef _1 InputDomain;
|
||||
|
||||
template <typename InOutPortalType>
|
||||
VTKM_EXEC void operator()(vtkm::Id index, InOutPortalType& comp) const
|
||||
{
|
||||
while (comp.Get(comp.Get(index)) != comp.Get(index))
|
||||
comp.Set(index, comp.Get(comp.Get(index)));
|
||||
|
||||
//vtkm::Id parent = comp.Get(index);
|
||||
//comp.Set(index, comp.Get(comp.Get(index)));
|
||||
};
|
||||
};
|
||||
|
||||
class IsStar : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<IdType> index, WholeArrayIn<IdType> comp, FieldOut<bool>);
|
||||
typedef _3 ExecutionSignature(_1, _2);
|
||||
typedef _1 InputDomain;
|
||||
|
||||
template <typename InOutPortalType>
|
||||
VTKM_EXEC bool operator()(vtkm::Id index, InOutPortalType& comp) const
|
||||
{
|
||||
return comp.Get(index) == comp.Get(comp.Get(index));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
class GraphConnectivity
|
||||
{
|
||||
public:
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
|
||||
|
||||
template <typename InputPortalType, typename OutputPortalType>
|
||||
void Run(const InputPortalType& numIndexArray,
|
||||
const InputPortalType& indexOffsetArray,
|
||||
const InputPortalType& connectivityArray,
|
||||
OutputPortalType& componentsOut) const
|
||||
{
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
|
||||
|
||||
bool allStar = false;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> components;
|
||||
vtkm::cont::ArrayHandle<bool> isStar;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellIds;
|
||||
Algorithm::Copy(
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id>(0, 1, numIndexArray.GetNumberOfValues()), cellIds);
|
||||
Algorithm::Copy(cellIds, components);
|
||||
|
||||
do
|
||||
{
|
||||
vtkm::worklet::DispatcherMapField<Graft> graftDispatcher;
|
||||
graftDispatcher.Invoke(
|
||||
cellIds, indexOffsetArray, numIndexArray, connectivityArray, components);
|
||||
|
||||
// Detection of allStar has be come before pointer jumping. Don't try to rearrange it.
|
||||
vtkm::worklet::DispatcherMapField<IsStar> isStarDisp;
|
||||
isStarDisp.Invoke(cellIds, components, isStar);
|
||||
allStar = Algorithm::Reduce(isStar, true, vtkm::LogicalAnd());
|
||||
|
||||
vtkm::worklet::DispatcherMapField<PointerJumping> pointJumpingDispatcher;
|
||||
pointJumpingDispatcher.Invoke(cellIds, components);
|
||||
} while (!allStar);
|
||||
|
||||
// renumber connected component to the range of [0, number of components).
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> uniqueComponents;
|
||||
Algorithm::Copy(components, uniqueComponents);
|
||||
Algorithm::Sort(uniqueComponents);
|
||||
Algorithm::Unique(uniqueComponents);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> uniqueColor;
|
||||
Algorithm::Copy(
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id>(0, 1, uniqueComponents.GetNumberOfValues()),
|
||||
uniqueColor);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellColors;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> cellIdsOut;
|
||||
InnerJoin<DeviceAdapter>().Run(
|
||||
components, cellIds, uniqueComponents, uniqueColor, cellColors, cellIdsOut, componentsOut);
|
||||
|
||||
Algorithm::SortByKey(cellIdsOut, componentsOut);
|
||||
}
|
||||
};
|
||||
#endif //vtk_m_worklet_connectivity_graph_connectivity_h
|
105
vtkm/worklet/connectivities/InnerJoin.h
Normal file
105
vtkm/worklet/connectivities/InnerJoin.h
Normal file
@ -0,0 +1,105 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_worklet_InnerJoin_h
|
||||
#define vtk_m_worklet_InnerJoin_h
|
||||
|
||||
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
class InnerJoin
|
||||
{
|
||||
public:
|
||||
struct Merge : vtkm::worklet::WorkletMapField
|
||||
{
|
||||
typedef void ControlSignature(FieldIn<vtkm::Id>,
|
||||
FieldIn<vtkm::Id>,
|
||||
FieldIn<vtkm::Id>,
|
||||
WholeArrayIn<vtkm::Id>,
|
||||
FieldOut<>,
|
||||
FieldOut<>,
|
||||
FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, _2, _3, VisitIndex, _4, _5, _6, _7);
|
||||
using InputDomain = _1;
|
||||
|
||||
using ScatterType = vtkm::worklet::ScatterCounting;
|
||||
|
||||
VTKM_CONT
|
||||
ScatterType GetScatter() const { return this->Scatter; }
|
||||
|
||||
VTKM_CONT
|
||||
Merge(const ScatterType& scatter)
|
||||
: Scatter(scatter)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename InPortalType>
|
||||
VTKM_EXEC void operator()(vtkm::Id key,
|
||||
vtkm::Id value1,
|
||||
vtkm::Id lowerBounds,
|
||||
vtkm::Id visitIndex,
|
||||
const InPortalType& value2,
|
||||
vtkm::Id& keyOut,
|
||||
vtkm::Id& value1Out,
|
||||
vtkm::Id& value2Out) const
|
||||
{
|
||||
auto v2 = value2.Get(lowerBounds + visitIndex);
|
||||
keyOut = key;
|
||||
value1Out = value1;
|
||||
value2Out = v2;
|
||||
}
|
||||
|
||||
private:
|
||||
ScatterType Scatter;
|
||||
};
|
||||
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
|
||||
|
||||
// TODO: not mutating input keys and values?
|
||||
template <typename Key, typename Value1, typename Value2>
|
||||
void Run(vtkm::cont::ArrayHandle<Key>& key1,
|
||||
vtkm::cont::ArrayHandle<Value1>& value1,
|
||||
vtkm::cont::ArrayHandle<Key>& key2,
|
||||
vtkm::cont::ArrayHandle<Value2>& value2,
|
||||
vtkm::cont::ArrayHandle<Key>& keyOut,
|
||||
vtkm::cont::ArrayHandle<Value1>& value1Out,
|
||||
vtkm::cont::ArrayHandle<Value2>& value2Out) const
|
||||
{
|
||||
Algorithm::SortByKey(key1, value1);
|
||||
Algorithm::SortByKey(key2, value2);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> lbs;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> ubs;
|
||||
Algorithm::LowerBounds(key2, key1, lbs);
|
||||
Algorithm::UpperBounds(key2, key1, ubs);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> counts;
|
||||
Algorithm::Transform(ubs, lbs, counts, vtkm::Subtract());
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> output_offset;
|
||||
Algorithm::ScanExclusive(counts, output_offset);
|
||||
|
||||
vtkm::worklet::ScatterCounting scatter{ counts, DeviceAdapter() };
|
||||
Merge merge(scatter);
|
||||
vtkm::worklet::DispatcherMapField<Merge, DeviceAdapter> mergeDisp(merge);
|
||||
mergeDisp.Invoke(key1, value1, lbs, value2, keyOut, value1Out, value2Out);
|
||||
};
|
||||
};
|
||||
#endif //vtk_m_worklet_InnerJoin_h
|
@ -19,52 +19,55 @@
|
||||
##============================================================================
|
||||
|
||||
set(unit_tests
|
||||
UnitTestAverageByKey.cxx
|
||||
UnitTestCellAverage.cxx
|
||||
UnitTestCellDeepCopy.cxx
|
||||
UnitTestCellGradient.cxx
|
||||
UnitTestClipping.cxx
|
||||
UnitTestContourTreeUniform.cxx
|
||||
UnitTestCosmoTools.cxx
|
||||
UnitTestExternalFaces.cxx
|
||||
UnitTestExtractGeometry.cxx
|
||||
UnitTestExtractPoints.cxx
|
||||
UnitTestExtractStructured.cxx
|
||||
UnitTestFieldHistogram.cxx
|
||||
UnitTestFieldStatistics.cxx
|
||||
UnitTestKdTreeBuildNNS.cxx
|
||||
UnitTestKeys.cxx
|
||||
UnitTestMagnitude.cxx
|
||||
UnitTestMarchingCubes.cxx
|
||||
UnitTestMask.cxx
|
||||
UnitTestMaskPoints.cxx
|
||||
UnitTestNDimsEntropy.cxx
|
||||
UnitTestNDimsHistogram.cxx
|
||||
UnitTestNDimsHistMarginalization.cxx
|
||||
UnitTestParticleAdvection.cxx
|
||||
UnitTestPointElevation.cxx
|
||||
UnitTestPointGradient.cxx
|
||||
UnitTestRemoveUnusedPoints.cxx
|
||||
UnitTestScatterCounting.cxx
|
||||
UnitTestScatterPermutation.cxx
|
||||
UnitTestSplatKernels.cxx
|
||||
UnitTestStreamingSine.cxx
|
||||
UnitTestStreamLineUniformGrid.cxx
|
||||
UnitTestSurfaceNormals.cxx
|
||||
UnitTestTetrahedralize.cxx
|
||||
UnitTestThreshold.cxx
|
||||
UnitTestThresholdPoints.cxx
|
||||
UnitTestTriangulate.cxx
|
||||
UnitTestWholeCellSetIn.cxx
|
||||
UnitTestWorkletMapField.cxx
|
||||
UnitTestWorkletMapFieldExecArg.cxx
|
||||
UnitTestWorkletMapFieldWholeArray.cxx
|
||||
UnitTestWorkletMapPointNeighborhood.cxx
|
||||
UnitTestWorkletMapTopologyExplicit.cxx
|
||||
UnitTestWorkletMapTopologyUniform.cxx
|
||||
UnitTestWorkletReduceByKey.cxx
|
||||
UnitTestVertexClustering.cxx
|
||||
UnitTestWaveletCompressor.cxx
|
||||
# UnitTestAverageByKey.cxx
|
||||
# UnitTestCellAverage.cxx
|
||||
# UnitTestCellDeepCopy.cxx
|
||||
# UnitTestCellGradient.cxx
|
||||
# UnitTestClipping.cxx
|
||||
# UnitTestContourTreeUniform.cxx
|
||||
# UnitTestCosmoTools.cxx
|
||||
UnitTestDualGraph.cxx
|
||||
# UnitTestExternalFaces.cxx
|
||||
# UnitTestExtractGeometry.cxx
|
||||
# UnitTestExtractPoints.cxx
|
||||
# UnitTestExtractStructured.cxx
|
||||
# UnitTestFieldHistogram.cxx
|
||||
# UnitTestFieldStatistics.cxx
|
||||
UnitTestGraphConnectivity.cpp
|
||||
UnitTestInnerJoin.cxx
|
||||
# UnitTestKdTreeBuildNNS.cxx
|
||||
# UnitTestKeys.cxx
|
||||
# UnitTestMagnitude.cxx
|
||||
# UnitTestMarchingCubes.cxx
|
||||
# UnitTestMask.cxx
|
||||
# UnitTestMaskPoints.cxx
|
||||
# UnitTestNDimsEntropy.cxx
|
||||
# UnitTestNDimsHistogram.cxx
|
||||
# UnitTestNDimsHistMarginalization.cxx
|
||||
# UnitTestParticleAdvection.cxx
|
||||
# UnitTestPointElevation.cxx
|
||||
# UnitTestPointGradient.cxx
|
||||
# UnitTestRemoveUnusedPoints.cxx
|
||||
# UnitTestScatterCounting.cxx
|
||||
# UnitTestScatterPermutation.cxx
|
||||
# UnitTestSplatKernels.cxx
|
||||
# UnitTestStreamingSine.cxx
|
||||
# UnitTestStreamLineUniformGrid.cxx
|
||||
# UnitTestSurfaceNormals.cxx
|
||||
# UnitTestTetrahedralize.cxx
|
||||
# UnitTestThreshold.cxx
|
||||
# UnitTestThresholdPoints.cxx
|
||||
# UnitTestTriangulate.cxx
|
||||
# UnitTestWholeCellSetIn.cxx
|
||||
# UnitTestWorkletMapField.cxx
|
||||
# UnitTestWorkletMapFieldExecArg.cxx
|
||||
# UnitTestWorkletMapFieldWholeArray.cxx
|
||||
# UnitTestWorkletMapPointNeighborhood.cxx
|
||||
# UnitTestWorkletMapTopologyExplicit.cxx
|
||||
# UnitTestWorkletMapTopologyUniform.cxx
|
||||
# UnitTestWorkletReduceByKey.cxx
|
||||
# UnitTestVertexClustering.cxx
|
||||
# UnitTestWaveletCompressor.cxx
|
||||
)
|
||||
|
||||
vtkm_save_worklet_unit_tests(${unit_tests})
|
||||
|
217
vtkm/worklet/testing/UnitTestDualGraph.cxx
Normal file
217
vtkm/worklet/testing/UnitTestDualGraph.cxx
Normal file
@ -0,0 +1,217 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
#include <vtkm/exec/CellEdge.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/worklet/DispatcherReduceByKey.h>
|
||||
#include <vtkm/worklet/Keys.h>
|
||||
#include <vtkm/worklet/ScatterCounting.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
#include <vtkm/worklet/WorkletReduceByKey.h>
|
||||
|
||||
#include <vtkm/filter/MarchingCubes.h>
|
||||
#include <vtkm/worklet/connectivities/CellSetDualGraph.h>
|
||||
|
||||
class TangleField : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<IdType> vertexId, FieldOut<Scalar> v);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
typedef _1 InputDomain;
|
||||
|
||||
const vtkm::Id xdim, ydim, zdim;
|
||||
const vtkm::FloatDefault xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
const vtkm::Id cellsPerLayer;
|
||||
|
||||
VTKM_CONT
|
||||
TangleField(const vtkm::Id3 dims,
|
||||
const vtkm::FloatDefault mins[3],
|
||||
const vtkm::FloatDefault maxs[3])
|
||||
: xdim(dims[0])
|
||||
, ydim(dims[1])
|
||||
, zdim(dims[2])
|
||||
, xmin(mins[0])
|
||||
, ymin(mins[1])
|
||||
, zmin(mins[2])
|
||||
, xmax(maxs[0])
|
||||
, ymax(maxs[1])
|
||||
, zmax(maxs[2])
|
||||
, cellsPerLayer((xdim) * (ydim))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(const vtkm::Id& vertexId, vtkm::Float32& v) const
|
||||
{
|
||||
const vtkm::Id x = vertexId % (xdim);
|
||||
const vtkm::Id y = (vertexId / (xdim)) % (ydim);
|
||||
const vtkm::Id z = vertexId / cellsPerLayer;
|
||||
|
||||
const vtkm::FloatDefault fx =
|
||||
static_cast<vtkm::FloatDefault>(x) / static_cast<vtkm::FloatDefault>(xdim - 1);
|
||||
const vtkm::FloatDefault fy =
|
||||
static_cast<vtkm::FloatDefault>(y) / static_cast<vtkm::FloatDefault>(xdim - 1);
|
||||
const vtkm::FloatDefault fz =
|
||||
static_cast<vtkm::FloatDefault>(z) / static_cast<vtkm::FloatDefault>(xdim - 1);
|
||||
|
||||
const vtkm::Float32 xx = 3.0f * vtkm::Float32(xmin + (xmax - xmin) * (fx));
|
||||
const vtkm::Float32 yy = 3.0f * vtkm::Float32(ymin + (ymax - ymin) * (fy));
|
||||
const vtkm::Float32 zz = 3.0f * vtkm::Float32(zmin + (zmax - zmin) * (fz));
|
||||
|
||||
v = (xx * xx * xx * xx - 5.0f * xx * xx + yy * yy * yy * yy - 5.0f * yy * yy +
|
||||
zz * zz * zz * zz - 5.0f * zz * zz + 11.8f) *
|
||||
0.2f +
|
||||
0.5f;
|
||||
}
|
||||
};
|
||||
|
||||
vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
|
||||
const vtkm::Id3 vdims(dims[0] + 1, dims[1] + 1, dims[2] + 1);
|
||||
|
||||
vtkm::FloatDefault mins[3] = { -1.0f, -1.0f, -1.0f };
|
||||
vtkm::FloatDefault maxs[3] = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> pointFieldArray;
|
||||
vtkm::cont::ArrayHandleIndex vertexCountImplicitArray(vdims[0] * vdims[1] * vdims[2]);
|
||||
vtkm::worklet::DispatcherMapField<TangleField> tangleFieldDispatcher(
|
||||
TangleField(vdims, mins, maxs));
|
||||
tangleFieldDispatcher.Invoke(vertexCountImplicitArray, pointFieldArray);
|
||||
|
||||
vtkm::Id numCells = dims[0] * dims[1] * dims[2];
|
||||
auto cellFieldArray = vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(0, 1, numCells);
|
||||
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> origin(0.0f, 0.0f, 0.0f);
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> spacing(1.0f / static_cast<vtkm::FloatDefault>(dims[0]),
|
||||
1.0f / static_cast<vtkm::FloatDefault>(dims[2]),
|
||||
1.0f / static_cast<vtkm::FloatDefault>(dims[1]));
|
||||
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing);
|
||||
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));
|
||||
|
||||
static const vtkm::IdComponent ndim = 3;
|
||||
vtkm::cont::CellSetStructured<ndim> cellSet("cells");
|
||||
cellSet.SetPointDimensions(vdims);
|
||||
dataSet.AddCellSet(cellSet);
|
||||
|
||||
dataSet.AddField(vtkm::cont::Field("nodevar", vtkm::cont::Field::ASSOC_POINTS, pointFieldArray));
|
||||
dataSet.AddField(
|
||||
vtkm::cont::Field("cellvar", vtkm::cont::Field::ASSOC_CELL_SET, "cells", cellFieldArray));
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
class TestDualGraph
|
||||
{
|
||||
public:
|
||||
void TestTriangleMesh() const
|
||||
{
|
||||
// cell2vertices connectivityusing Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
|
||||
//std::vector<vtkm::Id> connectivity = {0, 2, 1, 1, 2, 4, 1, 4, 3, 2, 5, 4};
|
||||
std::vector<vtkm::Id> connectivity = { 0, 2, 4, 1, 3, 5, 2, 6, 4, 5, 3, 7, 2, 9, 6, 4, 6, 8 };
|
||||
|
||||
vtkm::cont::CellSetSingleType<> cellSet;
|
||||
cellSet.Fill(8, vtkm::CELL_SHAPE_TRIANGLE, 3, vtkm::cont::make_ArrayHandle(connectivity));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> numIndicesArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> indexOffsetArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> connectivityArray;
|
||||
|
||||
CellSetDualGraph<DeviceAdapter>().Run(
|
||||
cellSet, numIndicesArray, indexOffsetArray, connectivityArray);
|
||||
std::cout << "numIndices: ";
|
||||
for (int i = 0; i < numIndicesArray.GetNumberOfValues(); i++)
|
||||
{
|
||||
std::cout << numIndicesArray.GetPortalConstControl().Get(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "indexOffset: ";
|
||||
for (int i = 0; i < indexOffsetArray.GetNumberOfValues(); i++)
|
||||
{
|
||||
std::cout << indexOffsetArray.GetPortalConstControl().Get(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "connectivity: ";
|
||||
for (int i = 0; i < connectivityArray.GetNumberOfValues(); i++)
|
||||
{
|
||||
std::cout << connectivityArray.GetPortalConstControl().Get(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void TestIsosurface() const
|
||||
{
|
||||
vtkm::Id3 dims(3, 3, 3);
|
||||
vtkm::cont::DataSet dataSet = MakeIsosurfaceTestDataSet(dims);
|
||||
|
||||
vtkm::filter::MarchingCubes filter;
|
||||
filter.SetGenerateNormals(true);
|
||||
filter.SetMergeDuplicatePoints(true);
|
||||
filter.SetIsoValue(0, 0.5);
|
||||
vtkm::filter::Result result = filter.Execute(dataSet, dataSet.GetField("nodevar"));
|
||||
vtkm::cont::DataSet& outputData = result.GetDataSet();
|
||||
|
||||
auto cellSet = outputData.GetCellSet().Cast<vtkm::cont::CellSetSingleType<>>();
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> numIndicesArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> indexOffsetArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> connectivityArray;
|
||||
|
||||
CellSetDualGraph<DeviceAdapter>().Run(
|
||||
cellSet, numIndicesArray, indexOffsetArray, connectivityArray);
|
||||
std::cout << "numIndices: ";
|
||||
for (int i = 0; i < numIndicesArray.GetNumberOfValues(); i++)
|
||||
{
|
||||
std::cout << numIndicesArray.GetPortalConstControl().Get(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "indexOffset: ";
|
||||
for (int i = 0; i < indexOffsetArray.GetNumberOfValues(); i++)
|
||||
{
|
||||
std::cout << indexOffsetArray.GetPortalConstControl().Get(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "connectivity: ";
|
||||
for (int i = 0; i < connectivityArray.GetNumberOfValues(); i++)
|
||||
{
|
||||
std::cout << connectivityArray.GetPortalConstControl().Get(i) << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
void operator()() const
|
||||
{
|
||||
//this->TestTriangleMesh();
|
||||
this->TestIsosurface();
|
||||
}
|
||||
};
|
||||
|
||||
int UnitTestDualGraph(int, char* [])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(TestDualGraph<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>());
|
||||
}
|
209
vtkm/worklet/testing/UnitTestGraphConnectivity.cpp
Normal file
209
vtkm/worklet/testing/UnitTestGraphConnectivity.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/exec/CellEdge.h>
|
||||
#include <vtkm/worklet/ScatterCounting.h>
|
||||
#include <vtkm/worklet/Keys.h>
|
||||
#include <vtkm/worklet/WorkletReduceByKey.h>
|
||||
#include <vtkm/worklet/DispatcherReduceByKey.h>
|
||||
#include <vtkm/worklet/connectivities/CellSetDualGraph.h>
|
||||
#include <vtkm/worklet/connectivities/GraphConnectivity.h>
|
||||
|
||||
#include <vtkm/filter/MarchingCubes.h>
|
||||
|
||||
class TangleField : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<IdType> vertexId, FieldOut<Scalar> v);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
typedef _1 InputDomain;
|
||||
|
||||
const vtkm::Id xdim, ydim, zdim;
|
||||
const vtkm::FloatDefault xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
const vtkm::Id cellsPerLayer;
|
||||
|
||||
VTKM_CONT
|
||||
TangleField(const vtkm::Id3 dims,
|
||||
const vtkm::FloatDefault mins[3],
|
||||
const vtkm::FloatDefault maxs[3])
|
||||
: xdim(dims[0])
|
||||
, ydim(dims[1])
|
||||
, zdim(dims[2])
|
||||
, xmin(mins[0])
|
||||
, ymin(mins[1])
|
||||
, zmin(mins[2])
|
||||
, xmax(maxs[0])
|
||||
, ymax(maxs[1])
|
||||
, zmax(maxs[2])
|
||||
, cellsPerLayer((xdim) * (ydim))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void operator()(const vtkm::Id& vertexId, vtkm::Float32& v) const
|
||||
{
|
||||
const vtkm::Id x = vertexId % (xdim);
|
||||
const vtkm::Id y = (vertexId / (xdim)) % (ydim);
|
||||
const vtkm::Id z = vertexId / cellsPerLayer;
|
||||
|
||||
const vtkm::FloatDefault fx =
|
||||
static_cast<vtkm::FloatDefault>(x) / static_cast<vtkm::FloatDefault>(xdim - 1);
|
||||
const vtkm::FloatDefault fy =
|
||||
static_cast<vtkm::FloatDefault>(y) / static_cast<vtkm::FloatDefault>(xdim - 1);
|
||||
const vtkm::FloatDefault fz =
|
||||
static_cast<vtkm::FloatDefault>(z) / static_cast<vtkm::FloatDefault>(xdim - 1);
|
||||
|
||||
const vtkm::Float32 xx = 3.0f * vtkm::Float32(xmin + (xmax - xmin) * (fx));
|
||||
const vtkm::Float32 yy = 3.0f * vtkm::Float32(ymin + (ymax - ymin) * (fy));
|
||||
const vtkm::Float32 zz = 3.0f * vtkm::Float32(zmin + (zmax - zmin) * (fz));
|
||||
|
||||
v = (xx * xx * xx * xx - 5.0f * xx * xx + yy * yy * yy * yy - 5.0f * yy * yy +
|
||||
zz * zz * zz * zz - 5.0f * zz * zz + 11.8f) *
|
||||
0.2f +
|
||||
0.5f;
|
||||
}
|
||||
};
|
||||
|
||||
static vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
|
||||
const vtkm::Id3 vdims(dims[0] + 1, dims[1] + 1, dims[2] + 1);
|
||||
|
||||
vtkm::FloatDefault mins[3] = { -1.0f, -1.0f, -1.0f };
|
||||
vtkm::FloatDefault maxs[3] = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> pointFieldArray;
|
||||
vtkm::cont::ArrayHandleIndex vertexCountImplicitArray(vdims[0] * vdims[1] * vdims[2]);
|
||||
vtkm::worklet::DispatcherMapField<TangleField> tangleFieldDispatcher(
|
||||
TangleField(vdims, mins, maxs));
|
||||
tangleFieldDispatcher.Invoke(vertexCountImplicitArray, pointFieldArray);
|
||||
|
||||
vtkm::Id numCells = dims[0] * dims[1] * dims[2];
|
||||
auto cellFieldArray = vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(0, 1, numCells);
|
||||
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> origin(0.0f, 0.0f, 0.0f);
|
||||
vtkm::Vec<vtkm::FloatDefault, 3> spacing(1.0f / static_cast<vtkm::FloatDefault>(dims[0]),
|
||||
1.0f / static_cast<vtkm::FloatDefault>(dims[2]),
|
||||
1.0f / static_cast<vtkm::FloatDefault>(dims[1]));
|
||||
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing);
|
||||
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));
|
||||
|
||||
static const vtkm::IdComponent ndim = 3;
|
||||
vtkm::cont::CellSetStructured<ndim> cellSet("cells");
|
||||
cellSet.SetPointDimensions(vdims);
|
||||
dataSet.AddCellSet(cellSet);
|
||||
|
||||
dataSet.AddField(vtkm::cont::Field("nodevar", vtkm::cont::Field::ASSOC_POINTS, pointFieldArray));
|
||||
dataSet.AddField(
|
||||
vtkm::cont::Field("cellvar", vtkm::cont::Field::ASSOC_CELL_SET, "cells", cellFieldArray));
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
class TestGraphConnectivity
|
||||
{
|
||||
public:
|
||||
void TestGrafting() const
|
||||
{
|
||||
// std::vector<vtkm::Id> ids = {0, 1, 2, 3};
|
||||
// std::vector<vtkm::Id> conn = {1, 0, 2, 3, 1, 1};
|
||||
// std::vector<vtkm::Id> starts = {0, 1, 4, 5};
|
||||
// std::vector<vtkm::Id> ends = {1, 4, 5, 6};
|
||||
// std::vector<vtkm::Id> degrees = {1, 3, 1, 1};
|
||||
// std::vector<vtkm::Id> comp = {0, 1, 2, 3};
|
||||
|
||||
// std::vector<vtkm::Id> ids = {0, 1, 2, 3, 4};
|
||||
// std::vector<vtkm::Id> conn = {1, 2, 0, 2, 0, 1, 4, 3};
|
||||
// std::vector<vtkm::Id> starts = {0, 2, 4, 6, 7};
|
||||
// std::vector<vtkm::Id> ends = {2, 4, 6, 7, 8};
|
||||
// std::vector<vtkm::Id> degrees = {2, 2, 2, 1, 1};
|
||||
// std::vector<vtkm::Id> comp = {0, 1, 2, 3, 4};
|
||||
|
||||
// vtkm::cont::ArrayHandle<vtkm::Id> idsArr = vtkm::cont::make_ArrayHandle(ids);
|
||||
// vtkm::cont::ArrayHandle<vtkm::Id> connArr = vtkm::cont::make_ArrayHandle(conn);
|
||||
// vtkm::cont::ArrayHandle<vtkm::Id> startsArr = vtkm::cont::make_ArrayHandle(starts);
|
||||
// vtkm::cont::ArrayHandle<vtkm::Id> endsArr = vtkm::cont::make_ArrayHandle(ends);
|
||||
// vtkm::cont::ArrayHandle<vtkm::Id> degreesArr = vtkm::cont::make_ArrayHandle(degrees);
|
||||
// vtkm::cont::ArrayHandle<vtkm::Id> compArr = vtkm::cont::make_ArrayHandle(comp);
|
||||
// for (int i = 0; i < compArr.GetNumberOfValues(); i++) {
|
||||
// std::cout << compArr.GetPortalConstControl().Get(i) << " ";
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
|
||||
// std::vector<vtkm::Id> connectivity = { 0, 2, 4, 1, 3, 5, 2, 6, 4, 5, 3, 7, 2, 9, 6, 4, 6, 8};
|
||||
// vtkm::cont::CellSetSingleType<> cellSet;
|
||||
// cellSet.Fill(8,
|
||||
// vtkm::CELL_SHAPE_TRIANGLE,
|
||||
// 3,
|
||||
// vtkm::cont::make_ArrayHandle(connectivity));
|
||||
|
||||
vtkm::Id3 dims(4, 4, 4);
|
||||
vtkm::cont::DataSet dataSet = MakeIsosurfaceTestDataSet(dims);
|
||||
|
||||
vtkm::filter::MarchingCubes filter;
|
||||
filter.SetGenerateNormals(true);
|
||||
filter.SetMergeDuplicatePoints(true);
|
||||
filter.SetIsoValue(0, 0.1);
|
||||
vtkm::filter::Result result = filter.Execute(dataSet, dataSet.GetField("nodevar"));
|
||||
vtkm::cont::DataSet& outputData = result.GetDataSet();
|
||||
|
||||
auto cellSet = outputData.GetCellSet().Cast<vtkm::cont::CellSetSingleType<>>();
|
||||
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> numIndicesArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> indexOffsetArray;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> connectivityArray;
|
||||
|
||||
CellSetDualGraph<DeviceAdapter>().Run(cellSet,
|
||||
numIndicesArray,
|
||||
indexOffsetArray,
|
||||
connectivityArray);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> componentArray;
|
||||
GraphConnectivity<DeviceAdapter>().Run(numIndicesArray,
|
||||
indexOffsetArray,
|
||||
connectivityArray,
|
||||
componentArray);
|
||||
|
||||
for (int i = 0; i < componentArray.GetNumberOfValues(); i++)
|
||||
{
|
||||
std::cout << i << " "
|
||||
<< componentArray.GetPortalConstControl().Get(i) << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
this->TestGrafting();
|
||||
}
|
||||
};
|
||||
|
||||
int UnitTestGraphConnectivity(int, char *[])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(TestGraphConnectivity<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>());
|
||||
}
|
53
vtkm/worklet/testing/UnitTestInnerJoin.cxx
Normal file
53
vtkm/worklet/testing/UnitTestInnerJoin.cxx
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Created by ollie on 12/19/17.
|
||||
//
|
||||
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
#include <vtkm/worklet/ScatterCounting.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
|
||||
#include <vtkm/worklet/connectivities/InnerJoin.h>
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
class TestInnerJoin
|
||||
{
|
||||
public:
|
||||
void TestTwoArrays() const
|
||||
{
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
|
||||
|
||||
std::vector<vtkm::Id> A = { 8, 3, 6, 8, 9, 5, 12, 10, 14 };
|
||||
std::vector<vtkm::Id> B = { 7, 11, 9, 8, 5, 1, 0, 5 };
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> A_arr = vtkm::cont::make_ArrayHandle(A);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> B_arr = vtkm::cont::make_ArrayHandle(B);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> idxA;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> idxB;
|
||||
|
||||
Algorithm::Copy(vtkm::cont::ArrayHandleCounting<vtkm::Id>(0, 1, A_arr.GetNumberOfValues()),
|
||||
idxA);
|
||||
Algorithm::Copy(vtkm::cont::ArrayHandleCounting<vtkm::Id>(0, 1, B_arr.GetNumberOfValues()),
|
||||
idxB);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> joinedIndex;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> outA;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> outB;
|
||||
|
||||
InnerJoin<DeviceAdapter>().Run(A_arr, idxA, B_arr, idxB, joinedIndex, outA, outB);
|
||||
|
||||
for (int i = 0; i < joinedIndex.GetNumberOfValues(); i++)
|
||||
{
|
||||
std::cout << "key: " << joinedIndex.GetPortalConstControl().Get(i)
|
||||
<< ", value1: " << outA.GetPortalConstControl().Get(i)
|
||||
<< ", value2: " << outB.GetPortalConstControl().Get(i) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()() const { this->TestTwoArrays(); }
|
||||
};
|
||||
|
||||
int UnitTestInnerJoin(int, char* [])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(TestInnerJoin<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>());
|
||||
}
|
Loading…
Reference in New Issue
Block a user