Some fixes to VertexClustering
VertexClustering previously only worked with data of a specific floating point type (32 bit for point coordinates). Add some templates to accept either 32 bit or 64 bit floating points for point coordintes and be a bit more careful about implicit type conversions. I also made some changes to conform better with the VTK-m coding standards. The most common changes are using 2 space indentation for all block levels, capitolizing and using camel case for all class members, and prefixing "this->" to all use of internal class members.
This commit is contained in:
parent
ba20680728
commit
cc8a5d35ec
74
vtkm/exec/Assert.h
Normal file
74
vtkm/exec/Assert.h
Normal file
@ -0,0 +1,74 @@
|
||||
//============================================================================
|
||||
// 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 2015 Sandia Corporation.
|
||||
// Copyright 2015 UT-Battelle, LLC.
|
||||
// Copyright 2015 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_exec_Assert_h
|
||||
#define vtk_m_exec_Assert_h
|
||||
|
||||
#include <vtkm/internal/ExportMacros.h>
|
||||
|
||||
// Stringify macros for DAX_ASSERT_EXEC
|
||||
#define __VTKM_ASSERT_EXEC_STRINGIFY_2ND(s) #s
|
||||
#define __VTKM_ASSERT_EXEC_STRINGIFY(s) __VTKM_ASSERT_EXEC_STRINGIFY_2ND(s)
|
||||
|
||||
/// \def VTKM_ASSERT_EXEC(condition, work)
|
||||
///
|
||||
/// Asserts that \a condition resolves to true. If \a condition is false, then
|
||||
/// an error is raised. This macro is meant to work in the VTK-m execution
|
||||
/// environment and requires the \a work object to raise the error and throw it
|
||||
/// in the control environment.
|
||||
///
|
||||
#ifndef NDEBUG
|
||||
#define VTKM_ASSERT_EXEC(condition, work) \
|
||||
if (!(condition)) \
|
||||
::vtkm::exec::Assert( \
|
||||
condition, \
|
||||
__FILE__ ":" __VTKM_ASSERT_EXEC_STRINGIFY(__LINE__) ": " \
|
||||
"Assert Failed (" #condition ")", \
|
||||
work)
|
||||
#else
|
||||
//in release mode we just act like we use the result of the condition
|
||||
//and the worklet so that we don't introduce new issues.
|
||||
#define VTKM_ASSERT_EXEC(condition, work) \
|
||||
(void)(condition); \
|
||||
(void)(work);
|
||||
#endif
|
||||
|
||||
namespace vtkm {
|
||||
namespace exec {
|
||||
|
||||
/// Implements the assert functionality of VTKM_ASSERT_EXEC.
|
||||
///
|
||||
template<typename WorkType>
|
||||
VTKM_EXEC_EXPORT
|
||||
void Assert(bool condition, const char *message, WorkType work)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
else
|
||||
{
|
||||
work.RaiseError(message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::exec
|
||||
|
||||
#endif //vtk_m_exec_Assert_h
|
@ -19,6 +19,7 @@
|
||||
##============================================================================
|
||||
|
||||
set(headers
|
||||
Assert.h
|
||||
ExecutionObjectBase.h
|
||||
ExplicitConnectivity.h
|
||||
FunctorBase.h
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/Pair.h>
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
@ -46,7 +47,10 @@ struct DivideWorklet: public vtkm::worklet::WorkletMapField{
|
||||
|
||||
VTKM_EXEC_EXPORT void operator()(
|
||||
const ValueType &v, const vtkm::Id &count, ValueType &vout) const
|
||||
{ vout = v * (1./count); }
|
||||
{
|
||||
typedef typename VecTraits<ValueType>::ComponentType ComponentType;
|
||||
vout = v * ComponentType(1./count);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
|
@ -20,7 +20,9 @@
|
||||
#ifndef vtk_m_worklet_VertexClustering_h
|
||||
#define vtk_m_worklet_VertexClustering_h
|
||||
|
||||
#include <numeric>
|
||||
#include <vtkm/Math.h>
|
||||
|
||||
#include <vtkm/exec/Assert.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
@ -46,65 +48,59 @@
|
||||
namespace vtkm{ namespace worklet
|
||||
{
|
||||
|
||||
template <class DeviceAdapter>
|
||||
template<typename DeviceAdapter>
|
||||
struct VertexClustering{
|
||||
|
||||
typedef vtkm::Vec<vtkm::Float32,3> Vector3;
|
||||
typedef Vector3 PointType;
|
||||
|
||||
template<typename PointType>
|
||||
struct GridInfo
|
||||
{
|
||||
int dim[3];
|
||||
Vector3 origin;
|
||||
vtkm::Float64 grid_width;
|
||||
vtkm::Float64 inv_grid_width; // = 1/grid_width
|
||||
vtkm::Id dim[3];
|
||||
PointType origin;
|
||||
typename PointType::ComponentType grid_width;
|
||||
typename PointType::ComponentType inv_grid_width; // = 1/grid_width
|
||||
};
|
||||
|
||||
// input: points output: cid of the points
|
||||
template<typename PointType>
|
||||
class MapPointsWorklet : public vtkm::worklet::WorkletMapField {
|
||||
private:
|
||||
//const VTKM_EXEC_CONSTANT_EXPORT GridInfo grid;
|
||||
GridInfo grid;
|
||||
|
||||
VTKM_EXEC_EXPORT
|
||||
vtkm::Id min(vtkm::Id a, vtkm::Id b) const {
|
||||
return (a<b)?a:b;
|
||||
}
|
||||
//const VTKM_EXEC_CONSTANT_EXPORT GridInfo<PointType> Grid;
|
||||
GridInfo<PointType> Grid;
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<> , FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
typedef void ControlSignature(FieldIn<> , FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
MapPointsWorklet(const GridInfo &grid_)
|
||||
: grid(grid_)
|
||||
{ }
|
||||
VTKM_CONT_EXPORT
|
||||
MapPointsWorklet(const GridInfo<PointType> &grid)
|
||||
: Grid(grid)
|
||||
{ }
|
||||
|
||||
/// determine grid resolution for clustering
|
||||
VTKM_EXEC_EXPORT
|
||||
vtkm::Id get_cluster_id( const Vector3 &p) const
|
||||
{
|
||||
Vector3 p_rel = (p - grid.origin) * grid.inv_grid_width;
|
||||
vtkm::Id x = min((vtkm::Id)p_rel[0], grid.dim[0]-1);
|
||||
vtkm::Id y = min((vtkm::Id)p_rel[1], grid.dim[1]-1);
|
||||
vtkm::Id z = min((vtkm::Id)p_rel[2], grid.dim[2]-1);
|
||||
return x + grid.dim[0] * (y + grid.dim[1] * z); // get a unique hash value
|
||||
}
|
||||
/// determine grid resolution for clustering
|
||||
VTKM_EXEC_EXPORT
|
||||
vtkm::Id GetClusterId(const PointType &p) const
|
||||
{
|
||||
PointType p_rel = (p - this->Grid.origin) * this->Grid.inv_grid_width;
|
||||
vtkm::Id x = vtkm::Min((vtkm::Id)p_rel[0], this->Grid.dim[0]-1);
|
||||
vtkm::Id y = vtkm::Min((vtkm::Id)p_rel[1], this->Grid.dim[1]-1);
|
||||
vtkm::Id z = vtkm::Min((vtkm::Id)p_rel[2], this->Grid.dim[2]-1);
|
||||
return x + this->Grid.dim[0] * (y + this->Grid.dim[1] * z); // get a unique hash value
|
||||
}
|
||||
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(const PointType &point, vtkm::Id &cid) const
|
||||
{
|
||||
cid = get_cluster_id(point);
|
||||
VTKM_ASSERT_CONT(cid>=0); // the id could overflow if too many cells
|
||||
}
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(const PointType &point, vtkm::Id &cid) const
|
||||
{
|
||||
cid = this->GetClusterId(point);
|
||||
VTKM_ASSERT_EXEC(cid>=0, *this); // the id could overflow if too many cells
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class MapCellsWorklet: public vtkm::worklet::WorkletMapField {
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
|
||||
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst IdPortalType;
|
||||
IdPortalType pointIdPortal;
|
||||
IdPortalType pointCidPortal;
|
||||
IdPortalType numIndicesPortal;
|
||||
IdPortalType PointIdPortal;
|
||||
IdPortalType PointCidPortal;
|
||||
IdPortalType NumIndicesPortal;
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<> , FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
@ -113,18 +109,18 @@ struct VertexClustering{
|
||||
MapCellsWorklet(
|
||||
const IdArrayHandle &pointIdArray, // the given point Ids
|
||||
const IdArrayHandle &pointCidArray) // the cluser ids each pointId will map to
|
||||
: pointIdPortal(pointIdArray.PrepareForInput(DeviceAdapter()) ),
|
||||
pointCidPortal( pointCidArray.PrepareForInput(DeviceAdapter()))
|
||||
: PointIdPortal(pointIdArray.PrepareForInput(DeviceAdapter())),
|
||||
PointCidPortal(pointCidArray.PrepareForInput(DeviceAdapter()))
|
||||
{ }
|
||||
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(const vtkm::Id &pointIdIndex, vtkm::Id3 &cid3) const
|
||||
{
|
||||
//VTKM_ASSERT_CONT(pointIdIndex % 3 == 0); // TODO: may ignore non-triangle cells
|
||||
//VTKM_ASSERT_EXEC(pointIdIndex % 3 == 0, *this); // TODO: may ignore non-triangle cells
|
||||
// assume it's a triangle
|
||||
cid3[0] = pointCidPortal.Get( pointIdPortal.Get(pointIdIndex) );
|
||||
cid3[1] = pointCidPortal.Get( pointIdPortal.Get(pointIdIndex+1) );
|
||||
cid3[2] = pointCidPortal.Get( pointIdPortal.Get(pointIdIndex+2) );
|
||||
cid3[0] = this->PointCidPortal.Get( this->PointIdPortal.Get(pointIdIndex) );
|
||||
cid3[1] = this->PointCidPortal.Get( this->PointIdPortal.Get(pointIdIndex+1) );
|
||||
cid3[2] = this->PointCidPortal.Get( this->PointIdPortal.Get(pointIdIndex+2) );
|
||||
}
|
||||
};
|
||||
|
||||
@ -132,11 +128,11 @@ struct VertexClustering{
|
||||
class IndexingWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
|
||||
private:
|
||||
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::Portal IdPortalType;
|
||||
IdArrayHandle cidIndexArray;
|
||||
IdPortalType cidIndexRaw;
|
||||
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::Portal IdPortalType;
|
||||
IdArrayHandle CidIndexArray;
|
||||
IdPortalType CidIndexRaw;
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<>, FieldIn<>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
@ -144,19 +140,19 @@ struct VertexClustering{
|
||||
VTKM_CONT_EXPORT
|
||||
IndexingWorklet( vtkm::Id n )
|
||||
{
|
||||
cidIndexRaw = cidIndexArray.PrepareForOutput(n, DeviceAdapter() );
|
||||
this->CidIndexRaw = this->CidIndexArray.PrepareForOutput(n, DeviceAdapter() );
|
||||
}
|
||||
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(const vtkm::Id &counter, const vtkm::Id &cid) const
|
||||
{
|
||||
cidIndexRaw.Set(cid, counter);
|
||||
this->CidIndexRaw.Set(cid, counter);
|
||||
}
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
IdArrayHandle &getOutput()
|
||||
IdArrayHandle &GetOutput()
|
||||
{
|
||||
return cidIndexArray;
|
||||
return this->CidIndexArray;
|
||||
}
|
||||
};
|
||||
|
||||
@ -164,32 +160,32 @@ struct VertexClustering{
|
||||
class Cid2PointIdWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
|
||||
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
|
||||
private:
|
||||
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst IdPortalType;
|
||||
const IdPortalType cidIndexRaw;
|
||||
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst IdPortalType;
|
||||
const IdPortalType CidIndexRaw;
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
typedef void ControlSignature(FieldIn<>, FieldOut<>);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
Cid2PointIdWorklet( IdArrayHandle &cidIndexArray )
|
||||
: cidIndexRaw ( cidIndexArray.PrepareForInput(DeviceAdapter()) )
|
||||
{
|
||||
}
|
||||
VTKM_CONT_EXPORT
|
||||
Cid2PointIdWorklet( IdArrayHandle &cidIndexArray )
|
||||
: CidIndexRaw ( cidIndexArray.PrepareForInput(DeviceAdapter()) )
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(const vtkm::Id3 &cid3, vtkm::Id3 &pointId3) const
|
||||
VTKM_EXEC_EXPORT
|
||||
void operator()(const vtkm::Id3 &cid3, vtkm::Id3 &pointId3) const
|
||||
{
|
||||
if (cid3[0]==cid3[1] || cid3[0]==cid3[2] || cid3[1]==cid3[2])
|
||||
{
|
||||
if (cid3[0]==cid3[1] || cid3[0]==cid3[2] || cid3[1]==cid3[2])
|
||||
{
|
||||
pointId3[0] = pointId3[1] = pointId3[2] = -1 ; // invalid cell to be removed
|
||||
} else {
|
||||
pointId3[0] = cidIndexRaw.Get( cid3[0] );
|
||||
pointId3[1] = cidIndexRaw.Get( cid3[1] );
|
||||
pointId3[2] = cidIndexRaw.Get( cid3[2] );
|
||||
}
|
||||
pointId3[0] = pointId3[1] = pointId3[2] = -1 ; // invalid cell to be removed
|
||||
} else {
|
||||
pointId3[0] = this->CidIndexRaw.Get( cid3[0] );
|
||||
pointId3[1] = this->CidIndexRaw.Get( cid3[1] );
|
||||
pointId3[2] = this->CidIndexRaw.Get( cid3[2] );
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -215,33 +211,41 @@ public:
|
||||
/// \param ds : dataset
|
||||
/// \param bounds: dataset bounds
|
||||
/// \param nDivisions : number of max divisions per dimension
|
||||
template <class StorageT, class StorageU, class StorageV>
|
||||
void run(const vtkm::cont::ArrayHandle<PointType, StorageT> pointArray,
|
||||
template <typename FloatType,
|
||||
typename BoundsType,
|
||||
typename StorageT,
|
||||
typename StorageU,
|
||||
typename StorageV>
|
||||
void run(const vtkm::cont::ArrayHandle<vtkm::Vec<FloatType,3>, StorageT> pointArray,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, StorageU> pointIdArray,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, StorageV> cellToConnectivityIndexArray,
|
||||
const vtkm::Float64 bounds[6], vtkm::Id nDivisions,
|
||||
vtkm::cont::ArrayHandle<PointType> &output_pointArray,
|
||||
const BoundsType bounds[6], vtkm::Id nDivisions,
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<FloatType,3> > &output_pointArray,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> &output_pointId3Array)
|
||||
{
|
||||
/// determine grid resolution for clustering
|
||||
GridInfo gridInfo;
|
||||
{
|
||||
vtkm::Float64 res[3];
|
||||
for (int i=0; i<3; i++)
|
||||
res[i] = (bounds[i*2+1]-bounds[i*2])/nDivisions;
|
||||
gridInfo.grid_width = std::max(res[0], std::max(res[1], res[2]));
|
||||
typedef vtkm::Vec<FloatType,3> PointType;
|
||||
|
||||
vtkm::Float64 inv_grid_width = gridInfo.inv_grid_width = 1. / gridInfo.grid_width;
|
||||
/// determine grid resolution for clustering
|
||||
GridInfo<PointType> gridInfo;
|
||||
{
|
||||
FloatType res[3];
|
||||
for (vtkm::IdComponent i=0; i<3; i++)
|
||||
{
|
||||
res[i] = static_cast<FloatType>((bounds[i*2+1]-bounds[i*2])/nDivisions);
|
||||
}
|
||||
gridInfo.grid_width = vtkm::Max(res[0], vtkm::Max(res[1], res[2]));
|
||||
|
||||
FloatType inv_grid_width = gridInfo.inv_grid_width = FloatType(1) / gridInfo.grid_width;
|
||||
|
||||
//printf("Bounds: %lf, %lf, %lf, %lf, %lf, %lf\n", bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
|
||||
gridInfo.dim[0] = (int)ceil((bounds[1]-bounds[0])*inv_grid_width);
|
||||
gridInfo.dim[1] = (int)ceil((bounds[3]-bounds[2])*inv_grid_width);
|
||||
gridInfo.dim[2] = (int)ceil((bounds[5]-bounds[4])*inv_grid_width);
|
||||
gridInfo.dim[0] = (vtkm::Id)vtkm::Ceil((bounds[1]-bounds[0])*inv_grid_width);
|
||||
gridInfo.dim[1] = (vtkm::Id)vtkm::Ceil((bounds[3]-bounds[2])*inv_grid_width);
|
||||
gridInfo.dim[2] = (vtkm::Id)vtkm::Ceil((bounds[5]-bounds[4])*inv_grid_width);
|
||||
|
||||
// center the mesh in the grids
|
||||
gridInfo.origin[0] = (vtkm::Float32) ((bounds[1]+bounds[0])*0.5 - gridInfo.grid_width*(gridInfo.dim[0])*.5);
|
||||
gridInfo.origin[1] = (vtkm::Float32) ((bounds[3]+bounds[2])*0.5 - gridInfo.grid_width*(gridInfo.dim[1])*.5);
|
||||
gridInfo.origin[2] = (vtkm::Float32) ((bounds[5]+bounds[4])*0.5 - gridInfo.grid_width*(gridInfo.dim[2])*.5);
|
||||
gridInfo.origin[0] = static_cast<FloatType>((bounds[1]+bounds[0])*0.5 - gridInfo.grid_width*(gridInfo.dim[0])*.5);
|
||||
gridInfo.origin[1] = static_cast<FloatType>((bounds[3]+bounds[2])*0.5 - gridInfo.grid_width*(gridInfo.dim[1])*.5);
|
||||
gridInfo.origin[2] = static_cast<FloatType>((bounds[5]+bounds[4])*0.5 - gridInfo.grid_width*(gridInfo.dim[2])*.5);
|
||||
}
|
||||
|
||||
//construct the scheduler that will execute all the worklets
|
||||
@ -257,7 +261,8 @@ public:
|
||||
/// map points
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> pointCidArray;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<MapPointsWorklet>(MapPointsWorklet(gridInfo))
|
||||
vtkm::worklet::DispatcherMapField<MapPointsWorklet<PointType> >(
|
||||
MapPointsWorklet<PointType>(gridInfo))
|
||||
.Invoke(pointArray, pointCidArray );
|
||||
|
||||
#ifdef __VTKM_VERTEX_CLUSTERING_BENCHMARK
|
||||
@ -269,7 +274,7 @@ public:
|
||||
/// using pointCidArray as the key
|
||||
///
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> pointCidArrayReduced;
|
||||
vtkm::cont::ArrayHandle<Vector3> repPointArray; // representative point
|
||||
vtkm::cont::ArrayHandle<PointType> repPointArray; // representative point
|
||||
|
||||
vtkm::worklet::
|
||||
AverageByKey( pointCidArray, pointArray, pointCidArrayReduced, repPointArray );
|
||||
@ -306,8 +311,9 @@ public:
|
||||
///
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> pointId3Array;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<Cid2PointIdWorklet> ( Cid2PointIdWorklet( worklet3.getOutput() ) )
|
||||
.Invoke(cid3Array, pointId3Array);
|
||||
vtkm::worklet::DispatcherMapField<Cid2PointIdWorklet>(
|
||||
Cid2PointIdWorklet( worklet3.GetOutput() ) )
|
||||
.Invoke(cid3Array, pointId3Array);
|
||||
|
||||
|
||||
#ifdef __VTKM_VERTEX_CLUSTERING_BENCHMARK
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include <vtkm/worklet/VertexClustering.h>
|
||||
|
||||
template<typename T, int N>
|
||||
template<typename T, vtkm::IdComponent N>
|
||||
vtkm::cont::ArrayHandle<T> copyFromVec( vtkm::cont::ArrayHandle< vtkm::Vec<T, N> > const& other)
|
||||
{
|
||||
const T *vmem = reinterpret_cast< const T *>(& *other.GetPortalConstControl().GetIteratorBegin());
|
||||
@ -49,7 +49,9 @@ vtkm::cont::ArrayHandle<T> copyFromImplicit( vtkm::cont::ArrayHandle<T, StorageT
|
||||
return result;
|
||||
}
|
||||
|
||||
vtkm::cont::DataSet RunVertexClustering(vtkm::cont::DataSet &ds, const vtkm::Float64 bounds[6], int nDivisions)
|
||||
vtkm::cont::DataSet RunVertexClustering(vtkm::cont::DataSet &ds,
|
||||
const vtkm::Float64 bounds[6],
|
||||
vtkm::Id nDivisions)
|
||||
{
|
||||
typedef vtkm::Vec<vtkm::Float32,3> PointType;
|
||||
|
||||
@ -65,16 +67,21 @@ vtkm::cont::DataSet RunVertexClustering(vtkm::cont::DataSet &ds, const vtkm::Flo
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> output_pointId3Array ;
|
||||
|
||||
// run
|
||||
vtkm::worklet::VertexClustering<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>().run(pointArray, pointIdArray, cellToConnectivityIndexArray,
|
||||
bounds, nDivisions,
|
||||
output_pointArray, output_pointId3Array);
|
||||
vtkm::worklet::VertexClustering<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>().run(
|
||||
pointArray,
|
||||
pointIdArray,
|
||||
cellToConnectivityIndexArray,
|
||||
bounds,
|
||||
nDivisions,
|
||||
output_pointArray,
|
||||
output_pointId3Array);
|
||||
|
||||
vtkm::cont::DataSet new_ds;
|
||||
|
||||
new_ds.AddField(vtkm::cont::Field("xyz", 0, vtkm::cont::Field::ASSOC_POINTS, output_pointArray));
|
||||
new_ds.AddCoordinateSystem(vtkm::cont::CoordinateSystem("xyz"));
|
||||
|
||||
int cells = output_pointId3Array.GetNumberOfValues();
|
||||
vtkm::Id cells = output_pointId3Array.GetNumberOfValues();
|
||||
if (cells > 0)
|
||||
{
|
||||
//typedef typename vtkm::cont::ArrayHandleConstant<vtkm::Id>::StorageTag ConstantStorage;
|
||||
@ -98,8 +105,8 @@ vtkm::cont::DataSet RunVertexClustering(vtkm::cont::DataSet &ds, const vtkm::Flo
|
||||
|
||||
void TestVertexClustering()
|
||||
{
|
||||
double bounds[6];
|
||||
const int divisions = 3;
|
||||
vtkm::Float64 bounds[6];
|
||||
const vtkm::Id divisions = 3;
|
||||
vtkm::cont::testing::MakeTestDataSet maker;
|
||||
vtkm::cont::DataSet ds = maker.Make3DExplicitDataSetCowNose(bounds);
|
||||
|
||||
@ -107,18 +114,31 @@ void TestVertexClustering()
|
||||
vtkm::cont::DataSet ds_out = RunVertexClustering(ds, bounds, divisions);
|
||||
|
||||
// test
|
||||
const int output_pointIds = 9;
|
||||
int output_pointId[output_pointIds] = {1,2,5, 1,3,0, 1,5,4};
|
||||
const int output_points = 6;
|
||||
double output_point[output_points][3] = {{0.0174716003,0.0501927994,0.0930275023}, {0.0320714004,0.14704667,0.0952706337}, {0.0268670674,0.246195346,0.119720004}, {0.00215422804,0.0340906903,0.180881709}, {0.0108188,0.152774006,0.167914003}, {0.0202241503,0.225427493,0.140208006}};
|
||||
const vtkm::Id output_pointIds = 12;
|
||||
vtkm::Id output_pointId[output_pointIds] = {
|
||||
1,2,5,
|
||||
1,3,0,
|
||||
4,3,1,
|
||||
6,5,2
|
||||
};
|
||||
const vtkm::Id output_points = 7;
|
||||
// double output_point[output_points][3] = {{0.0174716003,0.0501927994,0.0930275023}, {0.0320714004,0.14704667,0.0952706337}, {0.0268670674,0.246195346,0.119720004}, {0.00215422804,0.0340906903,0.180881709}, {0.0108188,0.152774006,0.167914003}, {0.0202241503,0.225427493,0.140208006}};
|
||||
double output_point[output_points][3] = {
|
||||
{0.0174716,0.0501928,0.0930275},
|
||||
{0.0320714,0.147047,0.0952706},
|
||||
{0.0268671,0.246195,0.11972},
|
||||
{0.000631619,0.00311701,0.173352},
|
||||
{0.00418437,0.0753889,0.190921},
|
||||
{0.0144137,0.178567,0.156615},
|
||||
{0.0224398,0.246495,0.1351}
|
||||
};
|
||||
|
||||
vtkm::Id i;
|
||||
VTKM_TEST_ASSERT(ds_out.GetNumberOfFields() == 1, "Number of output fields mismatch");
|
||||
typedef vtkm::Vec<vtkm::Float32, 3> PointType;
|
||||
typedef vtkm::cont::ArrayHandle<PointType > PointArray;
|
||||
PointArray pointArray = ds_out.GetField(0).GetData().CastToArrayHandle<PointArray::ValueType, PointArray::StorageTag>();
|
||||
VTKM_TEST_ASSERT(pointArray.GetNumberOfValues() == output_points, "Number of output points mismatch" );
|
||||
for (i = 0; i < pointArray.GetNumberOfValues(); ++i)
|
||||
for (vtkm::Id i = 0; i < pointArray.GetNumberOfValues(); ++i)
|
||||
{
|
||||
const PointType &p1 = pointArray.GetPortalConstControl().Get(i);
|
||||
PointType p2 = vtkm::make_Vec<vtkm::Float32>((vtkm::Float32)output_point[i][0], (vtkm::Float32)output_point[i][1], (vtkm::Float32)output_point[i][2]) ;
|
||||
@ -131,7 +151,7 @@ void TestVertexClustering()
|
||||
VTKM_TEST_ASSERT(cellset, "CellSet Cast fail");
|
||||
vtkm::cont::ExplicitConnectivity<> &conn = cellset->GetNodeToCellConnectivity();
|
||||
VTKM_TEST_ASSERT(conn.GetConnectivityArray().GetNumberOfValues() == output_pointIds, "Number of connectivity array elements mismatch");
|
||||
for (i=0; i<conn.GetConnectivityArray().GetNumberOfValues(); i++)
|
||||
for (vtkm::Id i=0; i<conn.GetConnectivityArray().GetNumberOfValues(); i++)
|
||||
{
|
||||
vtkm::Id id1 = conn.GetConnectivityArray().GetPortalConstControl().Get(i) ;
|
||||
vtkm::Id id2 = output_pointId[i] ;
|
||||
|
Loading…
Reference in New Issue
Block a user