Merge branch 'advdatamodel'

This commit is contained in:
Mark Kim 2019-06-20 22:20:44 -04:00
commit cffd3873fc
37 changed files with 2592 additions and 61 deletions

@ -0,0 +1,81 @@
#ifndef vtk_m_cont_ArrayHandleExtrudeCoords_h
#define vtk_m_cont_ArrayHandleExtrudeCoords_h
#include <vtkm/cont/StorageExtrude.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayPortalExtrude.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/CoordinateSystem.hxx>
namespace vtkm
{
namespace cont
{
template <typename T>
class VTKM_ALWAYS_EXPORT ArrayHandleExtrudeCoords
: public vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, internal::StorageTagExtrude>
{
using StorageType = vtkm::cont::internal::Storage<vtkm::Vec<T, 3>, internal::StorageTagExtrude>;
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleExtrudeCoords,
(ArrayHandleExtrudeCoords<T>),
(vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, internal::StorageTagExtrude>));
ArrayHandleExtrudeCoords(const StorageType& storage)
: Superclass(storage)
{
}
vtkm::Int32 GetNumberOfPointsPerPlane() const { return (this->GetStorage().Length / 2); }
vtkm::Int32 GetNumberOfPlanes() const { return this->GetStorage().NumberOfPlanes; }
};
template <typename T>
vtkm::cont::ArrayHandleExtrudeCoords<T> make_ArrayHandleExtrudeCoords(
const T* array,
vtkm::Id length,
vtkm::Int32 numberOfPlanes,
bool cylindrical,
vtkm::CopyFlag copy = vtkm::CopyFlag::Off)
{
using StorageType = vtkm::cont::internal::Storage<vtkm::Vec<T, 3>, internal::StorageTagExtrude>;
if (copy == vtkm::CopyFlag::Off)
{
return ArrayHandleExtrudeCoords<T>(StorageType(array, length, numberOfPlanes, cylindrical));
}
else
{
auto storage = StorageType(
vtkm::cont::make_ArrayHandle(array, length, vtkm::CopyFlag::On), numberOfPlanes, cylindrical);
return ArrayHandleExtrudeCoords<T>(storage);
}
}
template <typename T>
vtkm::cont::ArrayHandleExtrudeCoords<T> make_ArrayHandleExtrudeCoords(
const std::vector<T>& array,
vtkm::Int32 numberOfPlanes,
bool cylindrical,
vtkm::CopyFlag copy = vtkm::CopyFlag::Off)
{
if (!array.empty())
{
return make_ArrayHandleExtrudeCoords(
&array.front(), static_cast<vtkm::Id>(array.size()), numberOfPlanes, cylindrical, copy);
}
else
{
// Vector empty. Just return an empty array handle.
return ArrayHandleExtrudeCoords<T>();
}
}
}
}
#endif

@ -0,0 +1,73 @@
#ifndef vtk_m_cont_ArrayHandleExtrudeField_h
#define vtk_m_cont_ArrayHandleExtrudeField_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayPortalExtrude.h>
#include <vtkm/cont/StorageExtrude.h>
namespace vtkm
{
namespace cont
{
template <typename T>
class VTKM_ALWAYS_EXPORT ArrayHandleExtrudeField
: public vtkm::cont::ArrayHandle<T, internal::StorageTagExtrude>
{
using StorageType = vtkm::cont::internal::Storage<T, internal::StorageTagExtrude>;
public:
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleExtrudeField,
(ArrayHandleExtrudeField<T>),
(vtkm::cont::ArrayHandle<T, internal::StorageTagExtrude>));
ArrayHandleExtrudeField(const StorageType& storage)
: Superclass(storage)
{
}
vtkm::Int32 GetNumberOfValuesPerPlane() const
{
return this->GetStorage().GetNumberOfValuesPerPlane();
}
vtkm::Int32 GetNumberOfPlanes() const { return this->GetStorage().GetNumberOfPlanes(); }
};
template <typename T>
vtkm::cont::ArrayHandleExtrudeField<T> make_ArrayHandleExtrudeField(
const T* array,
vtkm::Id length,
vtkm::Int32 numberOfPlanes,
bool cylindrical,
vtkm::CopyFlag copy = vtkm::CopyFlag::Off)
{
using StorageType = vtkm::cont::internal::Storage<T, internal::StorageTagExtrude>;
auto storage =
StorageType(vtkm::cont::make_ArrayHandle(array, length, copy), numberOfPlanes, cylindrical);
return ArrayHandleExtrudeField<T>(storage);
}
template <typename T>
vtkm::cont::ArrayHandleExtrudeField<T> make_ArrayHandleExtrudeField(
const std::vector<T>& array,
vtkm::Int32 numberOfPlanes,
bool cylindrical,
vtkm::CopyFlag copy = vtkm::CopyFlag::Off)
{
if (!array.empty())
{
return make_ArrayHandleExtrudeField(
array.data(), static_cast<vtkm::Id>(array.size()), numberOfPlanes, cylindrical, copy);
}
else
{
// Vector empty. Just return an empty array handle.
return ArrayHandleExtrudeField<T>();
}
}
}
} // vtkm::cont
#endif

@ -0,0 +1,145 @@
#ifndef vtk_m_internal_ArrayPortalExtrude_h
#define vtk_m_internal_ArrayPortalExtrude_h
#include <vtkm/internal/IndicesExtrude.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/ErrorInternal.h>
#include <vtkm/BaseComponent.h>
#include <vtkm/cont/StorageExtrude.h>
namespace vtkm
{
namespace exec
{
template <typename PortalType>
struct VTKM_ALWAYS_EXPORT ArrayPortalExtrude
{
using ValueType = vtkm::Vec<typename PortalType::ValueType, 3>;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalExtrude()
: Portal()
, NumberOfValues(0)
, NumberOfPlanes(0)
, UseCylindrical(false){};
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalExtrude(const PortalType& p,
vtkm::Int32 numOfValues,
vtkm::Int32 numOfPlanes,
bool cylindrical = false)
: Portal(p)
, NumberOfValues(numOfValues)
, NumberOfPlanes(numOfPlanes)
, UseCylindrical(cylindrical)
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const
{
return ((NumberOfValues / 2) * static_cast<vtkm::Id>(NumberOfPlanes));
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ValueType Get(vtkm::Id index) const;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ValueType Get(vtkm::Id2 index) const;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::Vec<ValueType, 6> GetWedge(const IndicesExtrude& index) const;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const {}
PortalType Portal;
vtkm::Int32 NumberOfValues;
vtkm::Int32 NumberOfPlanes;
bool UseCylindrical;
};
template <typename PortalType>
typename ArrayPortalExtrude<PortalType>::ValueType
ArrayPortalExtrude<PortalType>::ArrayPortalExtrude::Get(vtkm::Id index) const
{
using CompType = typename ValueType::ComponentType;
const vtkm::Id realIdx = (index * 2) % this->NumberOfValues;
const vtkm::Id whichPlane = (index * 2) / this->NumberOfValues;
const auto phi = static_cast<CompType>(whichPlane * (vtkm::TwoPi() / this->NumberOfPlanes));
auto r = this->Portal.Get(realIdx);
auto z = this->Portal.Get(realIdx + 1);
if (this->UseCylindrical)
{
return ValueType(r, phi, z);
}
else
{
return ValueType(r * vtkm::Cos(phi), r * vtkm::Sin(phi), z);
}
}
template <typename PortalType>
typename ArrayPortalExtrude<PortalType>::ValueType
ArrayPortalExtrude<PortalType>::ArrayPortalExtrude::Get(vtkm::Id2 index) const
{
using CompType = typename ValueType::ComponentType;
const vtkm::Id realIdx = (index[0] * 2);
const vtkm::Id whichPlane = index[1];
const auto phi = static_cast<CompType>(whichPlane * (vtkm::TwoPi() / this->NumberOfPlanes));
auto r = this->Portal.Get(realIdx);
auto z = this->Portal.Get(realIdx + 1);
if (this->UseCylindrical)
{
return ValueType(r, phi, z);
}
else
{
return ValueType(r * vtkm::Cos(phi), r * vtkm::Sin(phi), z);
}
}
template <typename PortalType>
vtkm::Vec<typename ArrayPortalExtrude<PortalType>::ValueType, 6>
ArrayPortalExtrude<PortalType>::ArrayPortalExtrude::GetWedge(const IndicesExtrude& index) const
{
using CompType = typename ValueType::ComponentType;
vtkm::Vec<ValueType, 6> result;
for (int j = 0; j < 2; ++j)
{
const auto phi =
static_cast<CompType>(index.Planes[j] * (vtkm::TwoPi() / this->NumberOfPlanes));
for (int i = 0; i < 3; ++i)
{
const vtkm::Id realIdx = index.PointIds[j][i] * 2;
auto r = this->Portal.Get(realIdx);
auto z = this->Portal.Get(realIdx + 1);
result[3 * j + i] = this->UseCylindrical
? ValueType(r, phi, z)
: ValueType(r * vtkm::Cos(phi), r * vtkm::Sin(phi), z);
}
}
return result;
}
}
}
#endif

@ -0,0 +1,215 @@
#ifndef vtk_m_internal_ArrayPortalExtrudePlane_h
#define vtk_m_internal_ArrayPortalExtrudePlane_h
#include <vtkm/internal/IndicesExtrude.h>
#include <vtkm/cont/ArrayHandle.h>
namespace vtkm
{
namespace exec
{
template <typename PortalType>
struct VTKM_ALWAYS_EXPORT ArrayPortalExtrudePlane
{
using ValueType = typename PortalType::ValueType;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalExtrudePlane()
: Portal()
, NumberOfPlanes(0){};
ArrayPortalExtrudePlane(const PortalType& p, vtkm::Int32 numOfPlanes)
: Portal(p)
, NumberOfPlanes(numOfPlanes)
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const
{
return this->Portal.GetNumberOfValues() * static_cast<vtkm::Id>(NumberOfPlanes);
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ValueType Get(vtkm::Id index) const { return this->Portal.Get(index % this->NumberOfPlanes); }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ValueType Get(vtkm::Id2 index) const { return this->Portal.Get(index[0]); }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::Vec<ValueType, 6> GetWedge(const IndicesExtrude& index) const;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const {}
PortalType Portal;
vtkm::Int32 NumberOfPlanes;
};
}
} // vtkm::exec
namespace vtkm
{
namespace cont
{
namespace internal
{
struct VTKM_ALWAYS_EXPORT StorageTagExtrudePlane
{
};
template <typename T>
class VTKM_ALWAYS_EXPORT Storage<T, internal::StorageTagExtrudePlane>
{
using HandleType = vtkm::cont::ArrayHandle<T>;
public:
using ValueType = T;
// This is meant to be invalid. Because point arrays are read only, you
// should only be able to use the const version.
struct PortalType
{
using ValueType = void*;
using IteratorType = void*;
};
using PortalConstType =
vtkm::exec::ArrayPortalExtrudePlane<typename HandleType::PortalConstControl>;
Storage()
: Array()
, NumberOfPlanes(0)
{
}
Storage(const HandleType& array, vtkm::Int32 numberOfPlanes)
: Array(array)
, NumberOfPlanes(numberOfPlanes)
{
}
PortalType GetPortal() { return PortalType{}; }
PortalConstType GetPortalConst() const
{
return PortalConstType(this->Array.GetPortalConstControl(), this->NumberOfPlanes);
}
vtkm::Id GetNumberOfValues() const
{
return this->Array.GetNumberOfValues() * static_cast<vtkm::Id>(this->NumberOfPlanes);
}
vtkm::Int32 GetNumberOfValuesPerPlane() const
{
return static_cast<vtkm::Int32>(this->Array->GetNumberOfValues());
}
vtkm::Int32 GetNumberOfPlanes() const { return this->NumberOfPlanes; }
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadType("ArrayPortalExtrudePlane is read only. It cannot be allocated.");
}
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadType("ArrayPortalExtrudePlane is read only. It cannot shrink.");
}
void ReleaseResources()
{
// This request is ignored since we don't own the memory that was past
// to us
}
private:
vtkm::cont::ArrayHandle<T> Array;
vtkm::Int32 NumberOfPlanes;
};
template <typename T, typename Device>
class VTKM_ALWAYS_EXPORT ArrayTransfer<T, internal::StorageTagExtrudePlane, Device>
{
public:
using ValueType = T;
using StorageType = vtkm::cont::internal::Storage<T, internal::StorageTagExtrudePlane>;
using PortalControl = typename StorageType::PortalType;
using PortalConstControl = typename StorageType::PortalConstType;
//meant to be an invalid writeable execution portal
using PortalExecution = typename StorageType::PortalType;
using PortalConstExecution = vtkm::exec::ArrayPortalExtrudePlane<decltype(
vtkm::cont::ArrayHandle<T>{}.PrepareForInput(Device{}))>;
VTKM_CONT
ArrayTransfer(StorageType* storage)
: ControlData(storage)
{
}
vtkm::Id GetNumberOfValues() const { return this->ControlData->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
return PortalConstExecution(this->ControlData->Array.PrepareForInput(Device()),
this->ControlData->NumberOfPlanes);
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool& vtkmNotUsed(updateData))
{
throw vtkm::cont::ErrorBadType("ArrayPortalExtrudePlane read only. "
"Cannot be used for in-place operations.");
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadType("ArrayPortalExtrudePlane read only. Cannot be used as output.");
}
VTKM_CONT
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
throw vtkm::cont::ErrorInternal(
"ArrayPortalExtrudePlane read only. "
"There should be no occurance of the ArrayHandle trying to pull "
"data from the execution environment.");
}
VTKM_CONT
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadType("ArrayPortalExtrudePlane read only. Cannot shrink.");
}
VTKM_CONT
void ReleaseResources()
{
// This request is ignored since we don't own the memory that was past
// to us
}
private:
const StorageType* const ControlData;
};
}
}
} // vtkm::cont::internal
#endif

@ -0,0 +1,24 @@
#include <vtkm/cont/ArrayPortalExtrudePlane.h>
namespace vtkm
{
namespace exec
{
template <typename PortalType>
vtkm::Vec<typename ArrayPortalExtrudePlane<PortalType>::ValueType, 6> ArrayPortalExtrudePlane<
PortalType>::ArrayPortalExtrudePlane::GetWedge(const ToroidIndices& index) const
{
vtkm::Vec<ValueType, 6> result;
result[0] = this->Portal.Get(index.PointIds[0][0]);
result[1] = this->Portal.Get(index.PointIds[0][1]);
result[2] = this->Portal.Get(index.PointIds[0][2]);
result[3] = this->Portal.Get(index.PointIds[1][0]);
result[4] = this->Portal.Get(index.PointIds[1][1]);
result[5] = this->Portal.Get(index.PointIds[1][2]);
return result;
}
}
} // vtkm::exec

@ -21,6 +21,8 @@ set(headers
ArrayHandleCounting.h
ArrayHandleDiscard.h
ArrayHandleExtractComponent.h
ArrayHandleExtrudeCoords.h
ArrayHandleExtrudeField.h
ArrayHandleGroupVec.h
ArrayHandleGroupVecVariable.h
ArrayHandleImplicit.h
@ -37,6 +39,8 @@ set(headers
ArrayHandleZip.h
ArrayPortal.h
ArrayPortalToIterators.h
ArrayPortalExtrude.h
ArrayPortalExtrudePlane.h
ArrayRangeCompute.h
AssignerMultiBlock.h
AtomicArray.h
@ -52,6 +56,7 @@ set(headers
CellLocatorUniformGrid.h
CellSet.h
CellSetExplicit.h
CellSetExtrude.h
CellSetListTag.h
CellSetPermutation.h
CellSetSingleType.h
@ -94,6 +99,7 @@ set(headers
Serialization.h
Storage.h
StorageBasic.h
StorageExtrude.h
StorageImplicit.h
StorageListTag.h
StorageVirtual.h
@ -106,9 +112,11 @@ set(headers
set(template_sources
ArrayHandle.hxx
ArrayPortalExtrudePlane.hxx
ArrayHandleVirtual.hxx
ArrayRangeCompute.hxx
CellSetExplicit.hxx
CellSetExtrude.hxx
CellSetStructured.hxx
ColorTable.hxx
CoordinateSystem.hxx
@ -153,6 +161,7 @@ set(sources
CellLocatorUniformGrid.cxx
CellSet.cxx
CellSetExplicit.cxx
CellSetExtrude.cxx
CellSetStructured.cxx
ColorTable.cxx
CoordinateSystem.cxx

@ -0,0 +1,171 @@
#include <vtkm/cont/CellSetExtrude.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/CellShape.h>
namespace vtkm
{
namespace cont
{
VTKM_CONT CellSetExtrude::CellSetExtrude(const std::string& name)
: vtkm::cont::CellSet(name)
, IsPeriodic(false)
, NumberOfPointsPerPlane(0)
, NumberOfCellsPerPlane(0)
, NumberOfPlanes(0)
, ReverseConnectivityBuilt(false)
{
}
VTKM_CONT CellSetExtrude::CellSetExtrude(const vtkm::cont::ArrayHandle<vtkm::Int32>& conn,
vtkm::Int32 numberOfPointsPerPlane,
vtkm::Int32 numberOfPlanes,
const vtkm::cont::ArrayHandle<vtkm::Int32>& nextNode,
bool periodic,
const std::string& name)
: vtkm::cont::CellSet(name)
, IsPeriodic(periodic)
, NumberOfPointsPerPlane(numberOfPointsPerPlane)
, NumberOfCellsPerPlane(conn.GetNumberOfValues() / 3)
, NumberOfPlanes(numberOfPlanes)
, Connectivity(conn)
, NextNode(nextNode)
, ReverseConnectivityBuilt(false)
{
}
vtkm::Int32 CellSetExtrude::GetNumberOfPlanes() const
{
return this->NumberOfPlanes;
}
vtkm::Id CellSetExtrude::GetNumberOfCells() const
{
if (this->IsPeriodic)
{
return static_cast<vtkm::Id>(this->NumberOfPlanes) *
static_cast<vtkm::Id>(this->NumberOfCellsPerPlane);
}
else
{
return static_cast<vtkm::Id>(this->NumberOfPlanes - 1) *
static_cast<vtkm::Id>(this->NumberOfCellsPerPlane);
}
}
vtkm::Id CellSetExtrude::GetNumberOfPoints() const
{
return static_cast<vtkm::Id>(this->NumberOfPlanes) *
static_cast<vtkm::Id>(this->NumberOfPointsPerPlane);
}
vtkm::Id CellSetExtrude::GetNumberOfFaces() const
{
return -1;
}
vtkm::Id CellSetExtrude::GetNumberOfEdges() const
{
return -1;
}
vtkm::UInt8 CellSetExtrude::GetCellShape(vtkm::Id) const
{
return vtkm::CellShapeTagWedge::Id;
}
vtkm::IdComponent CellSetExtrude::GetNumberOfPointsInCell(vtkm::Id) const
{
return 6;
}
void CellSetExtrude::GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const
{
auto conn = this->PrepareForInput(vtkm::cont::DeviceAdapterTagSerial{},
vtkm::TopologyElementTagPoint{},
vtkm::TopologyElementTagCell{});
auto indices = conn.GetIndices(id);
for (int i = 0; i < 6; ++i)
{
ptids[i] = indices[i];
}
}
std::shared_ptr<CellSet> CellSetExtrude::NewInstance() const
{
return std::make_shared<CellSetExtrude>();
}
void CellSetExtrude::DeepCopy(const CellSet* src)
{
const auto* other = dynamic_cast<const CellSetExtrude*>(src);
if (!other)
{
throw vtkm::cont::ErrorBadType("CellSetExplicit::DeepCopy types don't match");
}
this->IsPeriodic = other->IsPeriodic;
this->NumberOfPointsPerPlane = other->NumberOfPointsPerPlane;
this->NumberOfCellsPerPlane = other->NumberOfCellsPerPlane;
this->NumberOfPlanes = other->NumberOfPlanes;
vtkm::cont::ArrayCopy(other->Connectivity, this->Connectivity);
vtkm::cont::ArrayCopy(other->NextNode, this->NextNode);
this->ReverseConnectivityBuilt = other->ReverseConnectivityBuilt;
if (this->ReverseConnectivityBuilt)
{
vtkm::cont::ArrayCopy(other->RConnectivity, this->RConnectivity);
vtkm::cont::ArrayCopy(other->ROffsets, this->ROffsets);
vtkm::cont::ArrayCopy(other->RCounts, this->RCounts);
vtkm::cont::ArrayCopy(other->PrevNode, this->PrevNode);
}
}
void CellSetExtrude::ReleaseResourcesExecution()
{
this->Connectivity.ReleaseResourcesExecution();
this->NextNode.ReleaseResourcesExecution();
this->RConnectivity.ReleaseResourcesExecution();
this->ROffsets.ReleaseResourcesExecution();
this->RCounts.ReleaseResourcesExecution();
this->PrevNode.ReleaseResourcesExecution();
}
VTKM_CONT vtkm::Id2 CellSetExtrude::GetSchedulingRange(vtkm::TopologyElementTagCell) const
{
if (this->IsPeriodic)
{
return vtkm::Id2(this->NumberOfCellsPerPlane, this->NumberOfPlanes);
}
else
{
return vtkm::Id2(this->NumberOfCellsPerPlane, this->NumberOfPlanes - 1);
}
}
VTKM_CONT vtkm::Id2 CellSetExtrude::GetSchedulingRange(vtkm::TopologyElementTagPoint) const
{
return vtkm::Id2(this->NumberOfPointsPerPlane, this->NumberOfPlanes);
}
void CellSetExtrude::PrintSummary(std::ostream& out) const
{
out << " vtkmCellSetSingleType: " << this->Name << std::endl;
out << " NumberOfCellsPerPlane: " << this->NumberOfCellsPerPlane << std::endl;
out << " NumberOfPointsPerPlane: " << this->NumberOfPointsPerPlane << std::endl;
out << " NumberOfPlanes: " << this->NumberOfPlanes << std::endl;
out << " Connectivity: " << std::endl;
vtkm::cont::printSummary_ArrayHandle(this->Connectivity, out);
out << " NextNode: " << std::endl;
vtkm::cont::printSummary_ArrayHandle(this->NextNode, out);
out << " ReverseConnectivityBuilt: " << this->NumberOfPlanes << std::endl;
}
}
} // vtkm::cont

136
vtkm/cont/CellSetExtrude.h Normal file

@ -0,0 +1,136 @@
#ifndef vtk_m_cont_CellSetExtrude_h
#define vtk_m_cont_CellSetExtrude_h
#include <vtkm/TopologyElementTag.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleExtrudeCoords.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/exec/ConnectivityExtrude.h>
#include <vtkm/exec/arg/ThreadIndicesExtrude.h>
#include <vtkm/worklet/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{
namespace cont
{
class VTKM_ALWAYS_EXPORT CellSetExtrude : public CellSet
{
public:
CellSetExtrude(const std::string& name = "extrude");
CellSetExtrude(const vtkm::cont::ArrayHandle<vtkm::Int32>& conn,
vtkm::Int32 numberOfPointsPerPlane,
vtkm::Int32 numberOfPlanes,
const vtkm::cont::ArrayHandle<vtkm::Int32>& nextNode,
bool periodic,
const std::string& name = "extrude");
vtkm::Int32 GetNumberOfPlanes() const;
vtkm::Id GetNumberOfCells() const override;
vtkm::Id GetNumberOfPoints() const override;
vtkm::Id GetNumberOfFaces() const override;
vtkm::Id GetNumberOfEdges() const override;
vtkm::Id2 GetSchedulingRange(vtkm::TopologyElementTagCell) const;
vtkm::Id2 GetSchedulingRange(vtkm::TopologyElementTagPoint) const;
vtkm::UInt8 GetCellShape(vtkm::Id id) const override;
vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id id) const override;
void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override;
std::shared_ptr<CellSet> NewInstance() const override;
void DeepCopy(const CellSet* src) override;
void PrintSummary(std::ostream& out) const override;
void ReleaseResourcesExecution() override;
template <typename DeviceAdapter>
using ConnectivityP2C = vtkm::exec::ConnectivityExtrude<DeviceAdapter>;
template <typename DeviceAdapter>
using ConnectivityC2P = vtkm::exec::ReverseConnectivityExtrude<DeviceAdapter>;
template <typename DeviceAdapter, typename FromTopology, typename ToTopology>
struct ExecutionTypes;
template <typename DeviceAdapter>
struct ExecutionTypes<DeviceAdapter, vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell>
{
using ExecObjectType = ConnectivityP2C<DeviceAdapter>;
};
template <typename DeviceAdapter>
struct ExecutionTypes<DeviceAdapter, vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint>
{
using ExecObjectType = ConnectivityC2P<DeviceAdapter>;
};
template <typename Device>
ConnectivityP2C<Device> PrepareForInput(Device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell) const;
template <typename Device>
ConnectivityC2P<Device> PrepareForInput(Device,
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint) const;
private:
template <typename Device>
void BuildReverseConnectivity(Device);
bool IsPeriodic;
vtkm::Int32 NumberOfPointsPerPlane;
vtkm::Int32 NumberOfCellsPerPlane;
vtkm::Int32 NumberOfPlanes;
vtkm::cont::ArrayHandle<vtkm::Int32> Connectivity;
vtkm::cont::ArrayHandle<vtkm::Int32> NextNode;
bool ReverseConnectivityBuilt;
vtkm::cont::ArrayHandle<vtkm::Int32> RConnectivity;
vtkm::cont::ArrayHandle<vtkm::Int32> ROffsets;
vtkm::cont::ArrayHandle<vtkm::Int32> RCounts;
vtkm::cont::ArrayHandle<vtkm::Int32> PrevNode;
};
template <typename T>
CellSetExtrude make_CellSetExtrude(const vtkm::cont::ArrayHandle<vtkm::Int32>& conn,
const vtkm::cont::ArrayHandleExtrudeCoords<T>& coords,
const vtkm::cont::ArrayHandle<vtkm::Int32>& nextNode,
bool periodic = true,
const std::string name = "extrude")
{
return CellSetExtrude{
conn, coords.GetNumberOfPointsPerPlane(), coords.GetNumberOfPlanes(), nextNode, periodic, name
};
}
template <typename T>
CellSetExtrude make_CellSetExtrude(const std::vector<vtkm::Int32>& conn,
const vtkm::cont::ArrayHandleExtrudeCoords<T>& coords,
const std::vector<vtkm::Int32>& nextNode,
bool periodic = true,
const std::string name = "extrude")
{
return CellSetExtrude{ vtkm::cont::make_ArrayHandle(conn),
coords.GetNumberOfPointsPerPlane(),
coords.GetNumberOfPlanes(),
vtkm::cont::make_ArrayHandle(nextNode),
periodic,
name };
}
}
} // vtkm::cont
#include <vtkm/cont/CellSetExtrude.hxx>
#endif

@ -0,0 +1,119 @@
//============================================================================
// 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.
//============================================================================
namespace
{
struct ComputeReverseMapping : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn cellIndex, WholeArrayOut cellIds);
using ExecutionSignature = void(_1, _2);
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename PortalType>
VTKM_EXEC void operator()(vtkm::Id cellId, PortalType&& pointIdValue) const
{
//3 as we are building the connectivity for triangles
const vtkm::Id offset = 3 * cellId;
pointIdValue.Set(offset, cellId);
pointIdValue.Set(offset + 1, cellId);
pointIdValue.Set(offset + 2, cellId);
}
};
struct ComputePrevNode : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn nextNode, WholeArrayOut prevNodeArray);
typedef void ExecutionSignature(InputIndex, _1, _2);
template <typename PortalType>
VTKM_EXEC void operator()(vtkm::Id idx, vtkm::Int32 next, PortalType& prevs) const
{
prevs.Set(static_cast<vtkm::Id>(next), static_cast<vtkm::Int32>(idx));
}
};
} // anonymous namespace
namespace vtkm
{
namespace cont
{
template <typename Device>
VTKM_CONT void CellSetExtrude::BuildReverseConnectivity(Device)
{
vtkm::worklet::Invoker invoke(Device{});
// create a mapping of where each key is the point id and the value
// is the cell id. We
const vtkm::Id numberOfPointsPerCell = 3;
const vtkm::Id rconnSize = this->NumberOfCellsPerPlane * numberOfPointsPerCell;
vtkm::cont::ArrayHandle<vtkm::Int32> pointIdKey;
vtkm::cont::DeviceAdapterAlgorithm<Device>::Copy(this->Connectivity, pointIdKey);
this->RConnectivity.Allocate(rconnSize);
invoke(ComputeReverseMapping{},
vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(0, 1, this->NumberOfCellsPerPlane),
this->RConnectivity);
vtkm::cont::DeviceAdapterAlgorithm<Device>::SortByKey(pointIdKey, this->RConnectivity);
// now we can compute the counts and offsets
vtkm::cont::ArrayHandle<vtkm::Int32> reducedKeys;
vtkm::cont::DeviceAdapterAlgorithm<Device>::ReduceByKey(
pointIdKey,
vtkm::cont::make_ArrayHandleConstant(vtkm::Int32(1), static_cast<vtkm::Int32>(rconnSize)),
reducedKeys,
this->RCounts,
vtkm::Add{});
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(this->RCounts, this->ROffsets);
// compute PrevNode from NextNode
this->PrevNode.Allocate(this->NextNode.GetNumberOfValues());
invoke(ComputePrevNode{}, this->NextNode, this->PrevNode);
this->ReverseConnectivityBuilt = true;
}
template <typename Device>
CellSetExtrude::ConnectivityP2C<Device> CellSetExtrude::PrepareForInput(
Device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell) const
{
return ConnectivityP2C<Device>(this->Connectivity.PrepareForInput(Device{}),
this->NextNode.PrepareForInput(Device{}),
this->NumberOfCellsPerPlane,
this->NumberOfPointsPerPlane,
this->NumberOfPlanes,
this->IsPeriodic);
}
template <typename Device>
VTKM_CONT CellSetExtrude::ConnectivityC2P<Device> CellSetExtrude::PrepareForInput(
Device,
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint) const
{
if (!this->ReverseConnectivityBuilt)
{
const_cast<CellSetExtrude*>(this)->BuildReverseConnectivity(Device{});
}
return ConnectivityC2P<Device>(this->RConnectivity.PrepareForInput(Device{}),
this->ROffsets.PrepareForInput(Device{}),
this->RCounts.PrepareForInput(Device{}),
this->PrevNode.PrepareForInput(Device{}),
this->NumberOfCellsPerPlane,
this->NumberOfPointsPerPlane,
this->NumberOfPlanes);
}
}
} // vtkm::cont

@ -17,6 +17,7 @@
#include <vtkm/ListTag.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/CellSetExtrude.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
@ -40,6 +41,7 @@ struct VTKM_ALWAYS_EXPORT CellSetListTagStructured3D
{
};
template <typename ShapeStorageTag = VTKM_DEFAULT_SHAPE_STORAGE_TAG,
typename NumIndicesStorageTag = VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG,
typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
@ -59,6 +61,7 @@ struct VTKM_ALWAYS_EXPORT CellSetListTagExplicitDefault : CellSetListTagExplicit
struct VTKM_ALWAYS_EXPORT CellSetListTagCommon : vtkm::ListTagBase<vtkm::cont::CellSetStructured<2>,
vtkm::cont::CellSetStructured<3>,
vtkm::cont::CellSetExplicit<>,
vtkm::cont::CellSetExtrude,
vtkm::cont::CellSetSingleType<>>
{
};

179
vtkm/cont/StorageExtrude.h Normal file

@ -0,0 +1,179 @@
#ifndef vtkm_internal_StorageExtrude_h
#define vtkm_internal_StorageExtrude_h
#include <vtkm/cont/ArrayPortalExtrude.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
struct VTKM_ALWAYS_EXPORT StorageTagExtrude
{
};
template <typename T>
class Storage<T, internal::StorageTagExtrude>
{
using BaseT = typename BaseComponent<T>::Type;
using HandleType = vtkm::cont::ArrayHandle<BaseT>;
using TPortalType = typename HandleType::PortalConstControl;
public:
using ValueType = T;
// This is meant to be invalid. Because point arrays are read only, you
// should only be able to use the const version.
struct PortalType
{
using ValueType = void*;
using IteratorType = void*;
};
using PortalConstType = exec::ArrayPortalExtrude<TPortalType>;
Storage()
: Array()
, Length(-1)
, NumberOfPlanes(0)
{
}
// Create with externally managed memory
Storage(const BaseT* array, vtkm::Id arrayLength, vtkm::Int32 numberOfPlanes, bool cylindrical)
: Array(vtkm::cont::make_ArrayHandle(array, arrayLength))
, Length(static_cast<vtkm::Int32>(arrayLength))
, NumberOfPlanes(numberOfPlanes)
, UseCylindrical(cylindrical)
{
VTKM_ASSERT(this->Length >= 0);
}
Storage(const HandleType& array, vtkm::Int32 numberOfPlanes, bool cylindrical)
: Array(array)
, Length(static_cast<vtkm::Int32>(array.GetNumberOfValues()))
, NumberOfPlanes(numberOfPlanes)
, UseCylindrical(cylindrical)
{
VTKM_ASSERT(this->Length >= 0);
}
PortalType GetPortal() { return PortalType{}; }
PortalConstType GetPortalConst() const
{
VTKM_ASSERT(this->Length >= 0);
return PortalConstType(this->Array.GetPortalConstControl(),
this->Length,
this->NumberOfPlanes,
this->UseCylindrical);
}
vtkm::Id GetNumberOfValues() const
{
VTKM_ASSERT(this->Length >= 0);
return (this->Length / 2) * static_cast<vtkm::Id>(this->NumberOfPlanes);
}
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadType("StorageTagExtrude is read only. It cannot be allocated.");
}
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadType("StoraageTagExtrue is read only. It cannot shrink.");
}
void ReleaseResources()
{
// This request is ignored since we don't own the memory that was past
// to us
}
vtkm::cont::ArrayHandle<BaseT> Array;
vtkm::Int32 Length;
vtkm::Int32 NumberOfPlanes;
bool UseCylindrical;
};
template <typename T, typename Device>
class VTKM_ALWAYS_EXPORT ArrayTransfer<T, internal::StorageTagExtrude, Device>
{
using BaseT = typename BaseComponent<T>::Type;
using TPortalType = decltype(vtkm::cont::ArrayHandle<BaseT>{}.PrepareForInput(Device{}));
public:
using ValueType = T;
using StorageType = vtkm::cont::internal::Storage<T, internal::StorageTagExtrude>;
using PortalControl = typename StorageType::PortalType;
using PortalConstControl = typename StorageType::PortalConstType;
//meant to be an invalid writeable execution portal
using PortalExecution = typename StorageType::PortalType;
using PortalConstExecution = vtkm::exec::ArrayPortalExtrude<TPortalType>;
VTKM_CONT
ArrayTransfer(StorageType* storage)
: ControlData(storage)
{
}
vtkm::Id GetNumberOfValues() const { return this->ControlData->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
return PortalConstExecution(this->ControlData->Array.PrepareForInput(Device()),
this->ControlData->Length,
this->ControlData->NumberOfPlanes,
this->ControlData->UseCylindrical);
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool& vtkmNotUsed(updateData))
{
throw vtkm::cont::ErrorBadType("StorageExtrude read only. "
"Cannot be used for in-place operations.");
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadType("StorageExtrude read only. Cannot be used as output.");
}
VTKM_CONT
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
throw vtkm::cont::ErrorInternal(
"ArrayHandleExrPointCoordinates read only. "
"There should be no occurance of the ArrayHandle trying to pull "
"data from the execution environment.");
}
VTKM_CONT
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadType("StorageExtrude read only. Cannot shrink.");
}
VTKM_CONT
void ReleaseResources()
{
// This request is ignored since we don't own the memory that was past
// to us
}
private:
const StorageType* const ControlData;
};
}
}
}
#endif

@ -28,4 +28,4 @@ set(unit_tests
UnitTestCudaPointLocatorUniformGrid.cu
UnitTestCudaVirtualObjectHandle.cu
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} LIBRARIES vtkm_worklet)

@ -25,7 +25,7 @@ set(unit_tests
UnitTestOpenMPPointLocatorUniformGrid.cxx
UnitTestOpenMPVirtualObjectHandle.cxx
)
vtkm_unit_tests(OpenMP SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)
vtkm_unit_tests(OpenMP SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG LIBRARIES vtkm_worklet)
if (VTKm_ENABLE_TESTING)
#We need to have all OpenMP tests run serially as they

@ -26,4 +26,4 @@ set(unit_tests
UnitTestSerialPointLocatorUniformGrid.cxx
UnitTestSerialVirtualObjectHandle.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG LIBRARIES vtkm_worklet)

@ -39,6 +39,7 @@ set(unit_tests
UnitTestArrayHandleCounting.cxx
UnitTestArrayHandleDiscard.cxx
UnitTestArrayHandleExtractComponent.cxx
UnitTestArrayHandleExtrude.cxx
UnitTestArrayHandleImplicit.cxx
UnitTestArrayHandleIndex.cxx
UnitTestArrayHandleReverse.cxx
@ -53,6 +54,7 @@ set(unit_tests
UnitTestCellLocatorGeneral.cxx
UnitTestCellSet.cxx
UnitTestCellSetExplicit.cxx
UnitTestCellSetExtrude.cxx
UnitTestCellSetPermutation.cxx
UnitTestContTesting.cxx
UnitTestDataSetBuilderExplicit.cxx

@ -0,0 +1,120 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/ArrayHandleExtrudeCoords.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
std::vector<float> points_rz = { 1.72485139f, 0.020562f, 1.73493571f,
0.02052826f, 1.73478011f, 0.02299051f }; //really a vec<float,2>
std::vector<float> correct_x_coords = {
1.72485139f, 1.73493571f, 1.73478011f, 1.21965411f, 1.22678481f, 1.22667478f,
1.05616686e-16f, 1.06234173e-16f, 1.06224646e-16f, -1.21965411f, -1.22678481f, -1.22667478f,
-1.72485139f, -1.73493571f, -1.73478011f, -1.21965411f, -1.22678481f, -1.22667478f,
-3.16850059e-16f, -3.18702520e-16f, -3.18673937e-16f, 1.21965411f, 1.22678481f, 1.22667478f
};
std::vector<float> correct_y_coords = { 0.0f,
0.0f,
0.0f,
1.21965411f,
1.22678481f,
1.22667478f,
1.72485139f,
1.73493571f,
1.73478011f,
1.21965411f,
1.22678481f,
1.22667478f,
2.11233373e-16f,
2.12468346e-16f,
2.12449291e-16f,
-1.21965411f,
-1.22678481f,
-1.22667478f,
-1.72485139f,
-1.73493571f,
-1.73478011f,
-1.21965411f,
-1.22678481f,
-1.22667478f };
std::vector<float> correct_z_coords = { 0.020562f, 0.02052826f, 0.02299051f, 0.020562f,
0.02052826f, 0.02299051f, 0.020562f, 0.02052826f,
0.02299051f, 0.020562f, 0.02052826f, 0.02299051f,
0.020562f, 0.02052826f, 0.02299051f, 0.020562f,
0.02052826f, 0.02299051f, 0.020562f, 0.02052826f,
0.02299051f, 0.020562f, 0.02052826f, 0.02299051f };
struct CopyValue : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn, FieldOut);
typedef _2 ExecutionSignature(_1);
template <typename T>
T&& operator()(T&& t) const
{
return std::forward<T>(t);
}
};
template <typename T, typename S>
void verify_results(vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, S> const& handle)
{
auto portal = handle.GetPortalConstControl();
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == static_cast<vtkm::Id>(correct_x_coords.size()),
"coordinate portal size is incorrect");
for (vtkm::Id i = 0; i < handle.GetNumberOfValues(); ++i)
{
auto v = portal.Get(i);
auto e = vtkm::make_Vec(correct_x_coords[static_cast<std::size_t>(i)],
correct_y_coords[static_cast<std::size_t>(i)],
correct_z_coords[static_cast<std::size_t>(i)]);
// std::cout << std::setprecision(4) << "computed " << v << " expected " << e << std::endl;
VTKM_TEST_ASSERT(test_equal(v, e), "incorrect conversion to Cartesian space");
}
}
int TestArrayHandleExtrude()
{
const int numPlanes = 8;
auto coords = vtkm::cont::make_ArrayHandleExtrudeCoords(points_rz, numPlanes, false);
VTKM_TEST_ASSERT(coords.GetNumberOfValues() ==
static_cast<vtkm::Id>(((points_rz.size() / 2) * numPlanes)),
"coordinate size is incorrect");
// Verify first that control is correct
verify_results(coords);
// Verify 1d scheduling by doing a copy to a vtkm::ArrayHandle<Vec3>
vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>> output1D;
vtkm::worklet::DispatcherMapField<CopyValue> dispatcher;
dispatcher.Invoke(coords, output1D);
verify_results(output1D);
return 0;
}
} // end namespace anonymous
int UnitTestArrayHandleExtrude(int argc, char* argv[])
{
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagSerial{});
return vtkm::cont::testing::Testing::Run(TestArrayHandleExtrude, argc, argv);
}

@ -0,0 +1,161 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/cont/ArrayHandleExtrudeCoords.h>
#include <vtkm/cont/CellSetExtrude.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CellAverage.h>
#include <vtkm/filter/PointAverage.h>
#include <vtkm/filter/PolicyExtrude.h>
namespace
{
std::vector<float> points_rz = { 1.72485139f, 0.020562f, 1.73493571f,
0.02052826f, 1.73478011f, 0.02299051f }; //really a vec<float,2>
std::vector<int> topology = { 0, 2, 1 };
std::vector<int> nextNode = { 0, 1, 2 };
struct CopyTopo : public vtkm::worklet::WorkletMapPointToCell
{
typedef void ControlSignature(CellSetIn, FieldOutCell);
typedef _2 ExecutionSignature(CellShape, PointIndices);
template <typename T>
T&& operator()(vtkm::CellShapeTagWedge, T&& t) const
{
return std::forward<T>(t);
}
};
struct CopyReverseCellCount : public vtkm::worklet::WorkletMapCellToPoint
{
typedef void ControlSignature(CellSetIn, FieldOutPoint);
typedef _2 ExecutionSignature(CellShape, CellCount, CellIndices);
template <typename T>
vtkm::Int32 operator()(vtkm::CellShapeTagVertex shape, vtkm::IdComponent count, T&& t) const
{
if (shape.Id == vtkm::CELL_SHAPE_VERTEX)
{
bool valid = true;
for (vtkm::IdComponent i = 0; i < count; ++i)
{
valid = valid && t[i] > 0;
}
return (valid && count == t.GetNumberOfComponents()) ? count : -1;
}
return -1;
}
};
template <typename T, typename S>
void verify_topo(vtkm::cont::ArrayHandle<vtkm::Vec<T, 6>, S> const& handle, vtkm::Id expectedLen)
{
auto portal = handle.GetPortalConstControl();
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == expectedLen, "topology portal size is incorrect");
for (vtkm::Id i = 0; i < expectedLen - 1; ++i)
{
auto v = portal.Get(i);
vtkm::Vec<int, 6> e;
e[0] = (topology[0] + (i * topology.size()));
e[1] = (topology[1] + (i * topology.size()));
e[2] = (topology[2] + (i * topology.size()));
e[3] = (topology[0] + ((i + 1) * topology.size()));
e[4] = (topology[1] + ((i + 1) * topology.size()));
e[5] = (topology[2] + ((i + 1) * topology.size()));
std::cout << "v, e: " << v << ", " << e << "\n";
VTKM_TEST_ASSERT(test_equal(v, e), "incorrect conversion of topology to Cartesian space");
}
auto v = portal.Get(expectedLen - 1);
vtkm::Vec<int, 6> e;
e[0] = (topology[0] + ((expectedLen - 1) * topology.size()));
e[1] = (topology[1] + ((expectedLen - 1) * topology.size()));
e[2] = (topology[2] + ((expectedLen - 1) * topology.size()));
e[3] = (topology[0]);
e[4] = (topology[1]);
e[5] = (topology[2]);
VTKM_TEST_ASSERT(test_equal(v, e), "incorrect conversion of topology to Cartesian space");
}
int TestCellSetExtrude()
{
const std::size_t numPlanes = 8;
auto coords = vtkm::cont::make_ArrayHandleExtrudeCoords(points_rz, numPlanes, false);
auto cells = vtkm::cont::make_CellSetExtrude(topology, coords, nextNode);
VTKM_TEST_ASSERT(cells.GetNumberOfPoints() == coords.GetNumberOfValues(),
"number of points don't match between cells and coordinates");
// Verify the topology by copying it into another array
{
vtkm::cont::ArrayHandle<vtkm::Vec<int, 6>> output;
vtkm::worklet::DispatcherMapTopology<CopyTopo> dispatcher;
dispatcher.Invoke(cells, output);
verify_topo(output, 8);
}
// Verify the reverse topology by copying the number of cells each point is
// used by it into another array
{
vtkm::cont::ArrayHandle<int> output;
vtkm::worklet::DispatcherMapTopology<CopyReverseCellCount> dispatcher;
dispatcher.Invoke(cells, output);
// verify_topo(output, 8);
}
//test a filter
vtkm::cont::DataSet dataset;
dataset.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coords", coords));
dataset.AddCellSet(cells);
// verify that a constant value point field can be accessed
std::vector<float> pvalues(coords.GetNumberOfValues(), 42.0f);
vtkm::cont::Field pfield(
"pfield", vtkm::cont::Field::Association::POINTS, vtkm::cont::make_ArrayHandle(pvalues));
dataset.AddField(pfield);
// verify that a constant cell value can be accessed
std::vector<float> cvalues(cells.GetNumberOfCells(), 42.0f);
vtkm::cont::Field cfield("cfield",
vtkm::cont::Field::Association::CELL_SET,
cells.GetName(),
vtkm::cont::make_ArrayHandle(cvalues));
dataset.AddField(cfield);
vtkm::filter::PointAverage avg;
try
{
avg.SetActiveField("cfield");
auto result = avg.Execute(dataset, PolicyExtrude{});
VTKM_TEST_ASSERT(result.HasField("cfield", vtkm::cont::Field::Association::POINTS),
"filter resulting dataset should be valid");
}
catch (const vtkm::cont::Error& err)
{
std::cout << err.GetMessage() << std::endl;
VTKM_TEST_ASSERT(false, "Filter execution threw an exception");
}
return 0;
}
}
int UnitTestCellSetExtrude(int argc, char* argv[])
{
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagSerial{});
return vtkm::cont::testing::Testing::Run(TestCellSetExtrude, argc, argv);
}

@ -23,6 +23,7 @@ set(headers
CellMeasure.h
ColorTable.h
ConnectivityExplicit.h
ConnectivityExtrude.h
ConnectivityPermuted.h
ConnectivityStructured.h
ExecutionWholeArray.h

@ -0,0 +1,247 @@
#ifndef vtk_m_exec_ConnectivityExtrude_h
#define vtk_m_exec_ConnectivityExtrude_h
#include <vtkm/internal/IndicesExtrude.h>
#include <vtkm/CellShape.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/exec/arg/ThreadIndicesTopologyMap.h>
namespace vtkm
{
namespace exec
{
template <typename Device>
class VTKM_ALWAYS_EXPORT ConnectivityExtrude
{
private:
using Int32HandleType = vtkm::cont::ArrayHandle<vtkm::Int32>;
using Int32PortalType = typename Int32HandleType::template ExecutionTypes<Device>::PortalConst;
public:
using ConnectivityPortalType = Int32PortalType;
using NextNodePortalType = Int32PortalType;
using SchedulingRangeType = vtkm::Id2;
using CellShapeTag = vtkm::CellShapeTagWedge;
using IndicesType = IndicesExtrude;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ConnectivityExtrude() = default;
ConnectivityExtrude(const ConnectivityPortalType& conn,
const NextNodePortalType& nextnode,
vtkm::Int32 cellsPerPlane,
vtkm::Int32 pointsPerPlane,
vtkm::Int32 numPlanes,
bool periodic);
VTKM_EXEC
vtkm::Id GetNumberOfElements() const { return this->NumberOfCells; }
VTKM_EXEC
CellShapeTag GetCellShape(vtkm::Id) const { return vtkm::CellShapeTagWedge(); }
VTKM_EXEC
IndicesType GetIndices(vtkm::Id index) const
{
return this->GetIndices(this->FlatToLogicalToIndex(index));
}
VTKM_EXEC
IndicesType GetIndices(const vtkm::Id2& index) const;
template <typename IndexType>
VTKM_EXEC vtkm::IdComponent GetNumberOfIndices(const IndexType& vtkmNotUsed(index)) const
{
return 6;
}
VTKM_EXEC
vtkm::Id LogicalToFlatToIndex(const vtkm::Id2& index) const
{
return index[0] + (index[1] * this->NumberOfCellsPerPlane);
};
VTKM_EXEC
vtkm::Id2 FlatToLogicalToIndex(vtkm::Id index) const
{
const vtkm::Id cellId = index % this->NumberOfCellsPerPlane;
const vtkm::Id plane = index / this->NumberOfCellsPerPlane;
return vtkm::Id2(cellId, plane);
}
private:
ConnectivityPortalType Connectivity;
NextNodePortalType NextNode;
vtkm::Int32 NumberOfCellsPerPlane;
vtkm::Int32 NumberOfPointsPerPlane;
vtkm::Int32 NumberOfPlanes;
vtkm::Id NumberOfCells;
};
template <typename Device>
class VTKM_ALWAYS_EXPORT ReverseConnectivityExtrude
{
private:
using Int32HandleType = vtkm::cont::ArrayHandle<vtkm::Int32>;
using Int32PortalType = typename Int32HandleType::template ExecutionTypes<Device>::PortalConst;
public:
using ConnectivityPortalType = Int32PortalType;
using OffsetsPortalType = Int32PortalType;
using CountsPortalType = Int32PortalType;
using PrevNodePortalType = Int32PortalType;
using SchedulingRangeType = vtkm::Id2;
using CellShapeTag = vtkm::CellShapeTagVertex;
using IndicesType = ReverseIndicesExtrude<ConnectivityPortalType>;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ReverseConnectivityExtrude() = default;
ReverseConnectivityExtrude(const ConnectivityPortalType& conn,
const OffsetsPortalType& offsets,
const CountsPortalType& counts,
const PrevNodePortalType& prevNode,
vtkm::Int32 cellsPerPlane,
vtkm::Int32 pointsPerPlane,
vtkm::Int32 numPlanes);
VTKM_EXEC
vtkm::Id GetNumberOfElements() const
{
return this->NumberOfPointsPerPlane * this->NumberOfPlanes;
}
VTKM_EXEC
CellShapeTag GetCellShape(vtkm::Id) const { return vtkm::CellShapeTagVertex(); }
/// Returns a Vec-like object containing the indices for the given index.
/// The object returned is not an actual array, but rather an object that
/// loads the indices lazily out of the connectivity array. This prevents
/// us from having to know the number of indices at compile time.
///
VTKM_EXEC
IndicesType GetIndices(vtkm::Id index) const
{
return this->GetIndices(this->FlatToLogicalToIndex(index));
}
VTKM_EXEC
IndicesType GetIndices(const vtkm::Id2& index) const;
template <typename IndexType>
VTKM_EXEC vtkm::IdComponent GetNumberOfIndices(const IndexType& index) const
{
return 1;
}
VTKM_EXEC
vtkm::Id LogicalToFlatToIndex(const vtkm::Id2& index) const
{
return index[0] + (index[1] * this->NumberOfPointsPerPlane);
};
VTKM_EXEC
vtkm::Id2 FlatToLogicalToIndex(vtkm::Id index) const
{
const vtkm::Id vertId = index % this->NumberOfPointsPerPlane;
const vtkm::Id plane = index / this->NumberOfPointsPerPlane;
return vtkm::Id2(vertId, plane);
}
ConnectivityPortalType Connectivity;
OffsetsPortalType Offsets;
CountsPortalType Counts;
PrevNodePortalType PrevNode;
vtkm::Int32 NumberOfCellsPerPlane;
vtkm::Int32 NumberOfPointsPerPlane;
vtkm::Int32 NumberOfPlanes;
};
template <typename Device>
ConnectivityExtrude<Device>::ConnectivityExtrude(const ConnectivityPortalType& conn,
const ConnectivityPortalType& nextNode,
vtkm::Int32 cellsPerPlane,
vtkm::Int32 pointsPerPlane,
vtkm::Int32 numPlanes,
bool periodic)
: Connectivity(conn)
, NextNode(nextNode)
, NumberOfCellsPerPlane(cellsPerPlane)
, NumberOfPointsPerPlane(pointsPerPlane)
, NumberOfPlanes(numPlanes)
{
this->NumberOfCells = periodic ? (static_cast<vtkm::Id>(cellsPerPlane) * numPlanes)
: (static_cast<vtkm::Id>(cellsPerPlane) * (numPlanes - 1));
}
template <typename Device>
typename ConnectivityExtrude<Device>::IndicesType ConnectivityExtrude<Device>::GetIndices(
const vtkm::Id2& index) const
{
vtkm::Id tr = index[0];
vtkm::Id p0 = index[1];
vtkm::Id p1 = (p0 < (this->NumberOfPlanes - 1)) ? (p0 + 1) : 0;
vtkm::Vec<vtkm::Int32, 3> pointIds1, pointIds2;
for (int i = 0; i < 3; ++i)
{
pointIds1[i] = this->Connectivity.Get((tr * 3) + i);
pointIds2[i] = this->NextNode.Get(pointIds1[i]);
}
return IndicesType(pointIds1, p0, pointIds2, p1, this->NumberOfPointsPerPlane);
}
template <typename Device>
ReverseConnectivityExtrude<Device>::ReverseConnectivityExtrude(const ConnectivityPortalType& conn,
const OffsetsPortalType& offsets,
const CountsPortalType& counts,
const PrevNodePortalType& prevNode,
vtkm::Int32 cellsPerPlane,
vtkm::Int32 pointsPerPlane,
vtkm::Int32 numPlanes)
: Connectivity(conn)
, Offsets(offsets)
, Counts(counts)
, PrevNode(prevNode)
, NumberOfCellsPerPlane(cellsPerPlane)
, NumberOfPointsPerPlane(pointsPerPlane)
, NumberOfPlanes(numPlanes)
{
}
template <typename Device>
typename ReverseConnectivityExtrude<Device>::IndicesType
ReverseConnectivityExtrude<Device>::GetIndices(const vtkm::Id2& index) const
{
auto ptCur = index[0];
auto ptPre = this->PrevNode.Get(ptCur);
auto plCur = index[1];
auto plPre = (plCur == 0) ? (this->NumberOfPlanes - 1) : (plCur - 1);
return IndicesType(this->Connectivity,
this->Offsets.Get(ptPre),
this->Counts.Get(ptPre),
this->Offsets.Get(ptCur),
this->Counts.Get(ptCur),
plPre,
plCur,
this->NumberOfCellsPerPlane);
}
}
} // namespace vtkm::exec
#endif

@ -15,6 +15,7 @@ set(headers
CellShape.h
ExecutionSignatureTagBase.h
Fetch.h
FetchExtrude.h
FetchTagArrayDirectIn.h
FetchTagArrayDirectInOut.h
FetchTagArrayDirectOut.h
@ -30,6 +31,7 @@ set(headers
OutputIndex.h
ThreadIndices.h
ThreadIndicesBasic.h
ThreadIndicesExtrude.h
ThreadIndicesPointNeighborhood.h
ThreadIndicesReduceByKey.h
ThreadIndicesTopologyMap.h

@ -0,0 +1,187 @@
#ifndef vtk_m_exec_arg_FetchExtrude_h
#define vtk_m_exec_arg_FetchExtrude_h
#include <vtkm/cont/ArrayPortalExtrude.h>
#include <vtkm/cont/ArrayPortalExtrudePlane.h>
#include <vtkm/exec/ConnectivityExtrude.h>
#include <vtkm/exec/arg/FetchTagArrayDirectIn.h>
#include <vtkm/exec/arg/FetchTagArrayTopologyMapIn.h>
#include <vtkm/exec/arg/FromIndices.h>
//optimized fetches for ArrayPortalExtrude for
// - 3D Scheduling
// - WorkletNeighboorhood
namespace vtkm
{
namespace exec
{
namespace arg
{
//Optimized fetch for point ids when iterating the cells ConnectivityExtrude
template <typename FetchType, typename Device, typename ExecObjectType>
struct Fetch<FetchType,
vtkm::exec::arg::AspectTagFromIndices,
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>,
ExecObjectType>
{
using ThreadIndicesType =
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>;
using ValueType = vtkm::Vec<vtkm::Id, 6>;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ValueType Load(const ThreadIndicesType& indices, const ExecObjectType&) const
{
// std::cout << "opimized fetch for point ids" << std::endl;
const auto& xgcidx = indices.GetIndicesFrom();
const vtkm::Id offset1 = (xgcidx.Planes[0] * xgcidx.NumberOfPointsPerPlane);
const vtkm::Id offset2 = (xgcidx.Planes[1] * xgcidx.NumberOfPointsPerPlane);
ValueType result;
result[0] = offset1 + xgcidx.PointIds[0][0];
result[1] = offset1 + xgcidx.PointIds[0][1];
result[2] = offset1 + xgcidx.PointIds[0][2];
result[3] = offset2 + xgcidx.PointIds[1][0];
result[4] = offset2 + xgcidx.PointIds[1][1];
result[5] = offset2 + xgcidx.PointIds[1][2];
return result;
}
VTKM_EXEC
void Store(const ThreadIndicesType&, const ExecObjectType&, const ValueType&) const
{
// Store is a no-op.
}
};
//Optimized fetch for point arrays when iterating the cells ConnectivityExtrude
template <typename Device, typename PortalType>
struct Fetch<vtkm::exec::arg::FetchTagArrayTopologyMapIn,
vtkm::exec::arg::AspectTagDefault,
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>,
PortalType>
{
using ThreadIndicesType =
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>;
using ValueType = vtkm::Vec<typename PortalType::ValueType, 6>;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ValueType Load(const ThreadIndicesType& indices, const PortalType& portal)
{
// std::cout << "opimized fetch for point values" << std::endl;
const auto& xgcidx = indices.GetIndicesFrom();
const vtkm::Id offset1 = (xgcidx.Planes[0] * xgcidx.NumberOfPointsPerPlane);
const vtkm::Id offset2 = (xgcidx.Planes[1] * xgcidx.NumberOfPointsPerPlane);
ValueType result;
result[0] = portal.Get(offset1 + xgcidx.PointIds[0][0]);
result[1] = portal.Get(offset1 + xgcidx.PointIds[0][1]);
result[2] = portal.Get(offset1 + xgcidx.PointIds[0][2]);
result[3] = portal.Get(offset2 + xgcidx.PointIds[1][0]);
result[4] = portal.Get(offset2 + xgcidx.PointIds[1][1]);
result[5] = portal.Get(offset2 + xgcidx.PointIds[1][2]);
return result;
}
VTKM_EXEC
void Store(const ThreadIndicesType&, const PortalType&, const ValueType&) const
{
// Store is a no-op for this fetch.
}
};
//Optimized fetch for point coordinates when iterating the cells of ConnectivityExtrude
template <typename Device, typename T>
struct Fetch<vtkm::exec::arg::FetchTagArrayTopologyMapIn,
vtkm::exec::arg::AspectTagDefault,
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>,
vtkm::exec::ArrayPortalExtrude<T>>
{
using ThreadIndicesType =
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>;
using ValueType = vtkm::Vec<typename vtkm::exec::ArrayPortalExtrude<T>::ValueType, 6>;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ValueType Load(const ThreadIndicesType& indices, const vtkm::exec::ArrayPortalExtrude<T>& points)
{
// std::cout << "opimized fetch for point coordinates" << std::endl;
return points.GetWedge(indices.GetIndicesFrom());
}
VTKM_EXEC
void Store(const ThreadIndicesType&,
const vtkm::exec::ArrayPortalExtrude<T>&,
const ValueType&) const
{
// Store is a no-op for this fetch.
}
};
//Optimized fetch for point coordinates when iterating the cells of ConnectivityExtrude
template <typename Device, typename T>
struct Fetch<vtkm::exec::arg::FetchTagArrayTopologyMapIn,
vtkm::exec::arg::AspectTagDefault,
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>,
vtkm::exec::ArrayPortalExtrudePlane<T>>
{
using ThreadIndicesType =
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>;
using ValueType = vtkm::Vec<typename vtkm::exec::ArrayPortalExtrudePlane<T>::ValueType, 6>;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ValueType Load(const ThreadIndicesType& indices,
const vtkm::exec::ArrayPortalExtrudePlane<T>& portal)
{
// std::cout << "opimized fetch for point coordinates" << std::endl;
return portal.GetWedge(indices.GetIndicesFrom());
}
VTKM_EXEC
void Store(const ThreadIndicesType&,
const vtkm::exec::ArrayPortalExtrudePlane<T>&,
const ValueType&) const
{
// Store is a no-op for this fetch.
}
};
//Optimized fetch for point coordinates when iterating the points of ConnectivityExtrude
template <typename Device, typename T>
struct Fetch<
vtkm::exec::arg::FetchTagArrayDirectIn,
vtkm::exec::arg::AspectTagDefault,
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ReverseConnectivityExtrude<Device>>,
vtkm::exec::ArrayPortalExtrude<T>>
{
using ThreadIndicesType =
vtkm::exec::arg::ThreadIndicesTopologyMap<vtkm::exec::ReverseConnectivityExtrude<Device>>;
using ValueType = typename vtkm::exec::ArrayPortalExtrude<T>::ValueType;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ValueType Load(const ThreadIndicesType& indices, const vtkm::exec::ArrayPortalExtrude<T>& points)
{
// std::cout << "opimized fetch for point coordinates" << std::endl;
return points.Get(indices.GetIndexLogical());
}
VTKM_EXEC
void Store(const ThreadIndicesType&,
const vtkm::exec::ArrayPortalExtrude<T>&,
const ValueType&) const
{
// Store is a no-op for this fetch.
}
};
}
}
}
#endif

@ -0,0 +1,301 @@
#ifndef vtk_m_exec_arg_ThreadIndicesExtrude_h
#define vtk_m_exec_arg_ThreadIndicesExtrude_h
#include <vtkm/exec/ConnectivityExtrude.h>
#include <vtkm/exec/arg/ThreadIndicesTopologyMap.h>
namespace vtkm
{
namespace exec
{
namespace arg
{
// Specialization for extrude types.
template <typename Device>
class ThreadIndicesTopologyMap<vtkm::exec::ConnectivityExtrude<Device>>
{
using ConnectivityType = vtkm::exec::ConnectivityExtrude<Device>;
public:
using CellShapeTag = typename ConnectivityType::CellShapeTag;
using IndicesFromType = typename ConnectivityType::IndicesType;
using LogicalIndexType = typename ConnectivityType::SchedulingRangeType;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC ThreadIndicesTopologyMap(vtkm::Id threadIndex,
vtkm::Id vtkmNotUsed(inputIndex),
vtkm::IdComponent vtkmNotUsed(visitIndex),
vtkm::Id vtkmNotUsed(outputIndex),
const ConnectivityType& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
{
const LogicalIndexType logicalIndex = detail::Deflate(threadIndex, LogicalIndexType());
const vtkm::Id index = connectivity.LogicalToFlatToIndex(logicalIndex);
this->ThreadIndex = index;
this->InputIndex = index;
this->OutputIndex = index;
this->VisitIndex = 0;
this->LogicalIndex = logicalIndex;
this->IndicesFrom = connectivity.GetIndices(logicalIndex);
//this->CellShape = connectivity.GetCellShape(index);
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex,
const ConnectivityType& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
{
// We currently only support multidimensional indices on one-to-one input-
// to-output mappings. (We don't have a use case otherwise.)
// That is why we treat teh threadIndex as also the inputIndex and outputIndex
const LogicalIndexType logicalIndex = detail::Deflate(threadIndex, LogicalIndexType());
const vtkm::Id index = connectivity.LogicalToFlatToIndex(logicalIndex);
this->ThreadIndex = index;
this->InputIndex = index;
this->OutputIndex = index;
this->VisitIndex = 0;
this->LogicalIndex = logicalIndex;
this->IndicesFrom = connectivity.GetIndices(logicalIndex);
//this->CellShape = connectivity.GetCellShape(index);
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
/// \brief The logical index into the input domain.
///
/// This is similar to \c GetIndex3D except the Vec size matches the actual
/// dimensions of the data.
///
VTKM_EXEC
LogicalIndexType GetIndexLogical() const { return this->LogicalIndex; }
/// \brief The index into the input domain.
///
/// This index refers to the input element (array value, cell, etc.) that
/// this thread is being invoked for. This is the typical index used during
/// fetches.
///
VTKM_EXEC
vtkm::Id GetInputIndex() const { return this->InputIndex; }
/// \brief The 3D index into the input domain.
///
/// Overloads the implementation in the base class to return the 3D index
/// for the input.
///
VTKM_EXEC
vtkm::Id3 GetInputIndex3D() const { return detail::InflateTo3D(this->GetIndexLogical()); }
/// \brief The index into the output domain.
///
/// This index refers to the output element (array value, cell, etc.) that
/// this thread is creating. This is the typical index used during
/// Fetch::Store.
///
VTKM_EXEC
vtkm::Id GetOutputIndex() const { return this->OutputIndex; }
/// \brief The visit index.
///
/// When multiple output indices have the same input index, they are
/// distinguished using the visit index.
///
VTKM_EXEC
vtkm::IdComponent GetVisitIndex() const { return this->VisitIndex; }
VTKM_EXEC
vtkm::Id GetGlobalIndex() const { return (this->GlobalThreadIndexOffset + this->OutputIndex); }
/// \brief The input indices of the "from" elements.
///
/// A topology map has "from" and "to" elements (for example from points to
/// cells). For each worklet invocation, there is exactly one "to" element,
/// but can be several "from" element. This method returns a Vec-like object
/// containing the indices to the "from" elements.
///
VTKM_EXEC
const IndicesFromType& GetIndicesFrom() const { return this->IndicesFrom; }
/// \brief The input indices of the "from" elements in pointer form.
///
/// Returns the same object as GetIndicesFrom except that it returns a
/// pointer to the internally held object rather than a reference or copy.
/// Since the from indices can be a sizeable Vec (8 entries is common), it is
/// best not to have a bunch a copies. Thus, you can pass around a pointer
/// instead. However, care should be taken to make sure that this object does
/// not go out of scope, at which time the returned pointer becomes invalid.
///
VTKM_EXEC
const IndicesFromType* GetIndicesFromPointer() const { return &this->IndicesFrom; }
/// \brief The shape of the input cell.
///
/// In topology maps that map from points to something, the indices make up
/// the structure of a cell. Although the shape tag is not technically and
/// index, it defines the meaning of the indices, so we put it here. (That
/// and this class is the only convenient place to store it.)
///
VTKM_EXEC
CellShapeTag GetCellShape() const { return vtkm::CellShapeTagWedge{}; }
private:
vtkm::Id ThreadIndex;
vtkm::Id InputIndex;
vtkm::IdComponent VisitIndex;
vtkm::Id OutputIndex;
LogicalIndexType LogicalIndex;
IndicesFromType IndicesFrom;
//CellShapeTag CellShape;
vtkm::Id GlobalThreadIndexOffset;
};
// Specialization for extrude types.
template <typename Device>
class ThreadIndicesTopologyMap<vtkm::exec::ReverseConnectivityExtrude<Device>>
{
using ConnectivityType = vtkm::exec::ReverseConnectivityExtrude<Device>;
public:
using CellShapeTag = typename ConnectivityType::CellShapeTag;
using IndicesFromType = typename ConnectivityType::IndicesType;
using LogicalIndexType = typename ConnectivityType::SchedulingRangeType;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ThreadIndicesTopologyMap(vtkm::Id& threadIndex,
vtkm::Id vtkmNotUsed(inputIndex),
vtkm::IdComponent vtkmNotUsed(visitIndex),
vtkm::Id vtkmNotUsed(outputIndex),
const ConnectivityType& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
{
const LogicalIndexType logicalIndex = detail::Deflate(threadIndex, LogicalIndexType());
const vtkm::Id index = connectivity.LogicalToFlatToIndex(logicalIndex);
this->ThreadIndex = index;
this->InputIndex = index;
this->OutputIndex = index;
this->VisitIndex = 0;
this->LogicalIndex = logicalIndex;
this->IndicesFrom = connectivity.GetIndices(logicalIndex);
//this->CellShape = connectivity.GetCellShape(index);
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex,
const ConnectivityType& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
{
const LogicalIndexType logicalIndex = detail::Deflate(threadIndex, LogicalIndexType());
const vtkm::Id index = connectivity.LogicalToFlatToIndex(logicalIndex);
this->ThreadIndex = index;
this->InputIndex = index;
this->OutputIndex = index;
this->VisitIndex = 0;
this->LogicalIndex = logicalIndex;
this->IndicesFrom = connectivity.GetIndices(logicalIndex);
//this->CellShape = connectivity.GetCellShape(index);
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
/// \brief The logical index into the input domain.
///
/// This is similar to \c GetIndex3D except the Vec size matches the actual
/// dimensions of the data.
///
VTKM_EXEC
LogicalIndexType GetIndexLogical() const { return this->LogicalIndex; }
/// \brief The index into the input domain.
///
/// This index refers to the input element (array value, cell, etc.) that
/// this thread is being invoked for. This is the typical index used during
/// fetches.
///
VTKM_EXEC
vtkm::Id GetInputIndex() const { return this->InputIndex; }
/// \brief The 3D index into the input domain.
///
/// Overloads the implementation in the base class to return the 3D index
/// for the input.
///
VTKM_EXEC
vtkm::Id3 GetInputIndex3D() const { return detail::InflateTo3D(this->GetIndexLogical()); }
/// \brief The index into the output domain.
///
/// This index refers to the output element (array value, cell, etc.) that
/// this thread is creating. This is the typical index used during
/// Fetch::Store.
///
VTKM_EXEC
vtkm::Id GetOutputIndex() const { return this->OutputIndex; }
/// \brief The visit index.
///
/// When multiple output indices have the same input index, they are
/// distinguished using the visit index.
///
VTKM_EXEC
vtkm::IdComponent GetVisitIndex() const { return this->VisitIndex; }
VTKM_EXEC
vtkm::Id GetGlobalIndex() const { return (this->GlobalThreadIndexOffset + this->OutputIndex); }
/// \brief The input indices of the "from" elements.
///
/// A topology map has "from" and "to" elements (for example from points to
/// cells). For each worklet invocation, there is exactly one "to" element,
/// but can be several "from" element. This method returns a Vec-like object
/// containing the indices to the "from" elements.
///
VTKM_EXEC
const IndicesFromType& GetIndicesFrom() const { return this->IndicesFrom; }
/// \brief The input indices of the "from" elements in pointer form.
///
/// Returns the same object as GetIndicesFrom except that it returns a
/// pointer to the internally held object rather than a reference or copy.
/// Since the from indices can be a sizeable Vec (8 entries is common), it is
/// best not to have a bunch a copies. Thus, you can pass around a pointer
/// instead. However, care should be taken to make sure that this object does
/// not go out of scope, at which time the returned pointer becomes invalid.
///
VTKM_EXEC
const IndicesFromType* GetIndicesFromPointer() const { return &this->IndicesFrom; }
/// \brief The shape of the input cell.
///
/// In topology maps that map from points to something, the indices make up
/// the structure of a cell. Although the shape tag is not technically and
/// index, it defines the meaning of the indices, so we put it here. (That
/// and this class is the only convenient place to store it.)
///
VTKM_EXEC
CellShapeTag GetCellShape() const { return vtkm::CellShapeTagVertex{}; }
private:
vtkm::Id ThreadIndex;
vtkm::Id InputIndex;
vtkm::IdComponent VisitIndex;
vtkm::Id OutputIndex;
LogicalIndexType LogicalIndex;
IndicesFromType IndicesFrom;
//CellShapeTag CellShape;
vtkm::Id GlobalThreadIndexOffset;
};
} //namespace arg
}
} // namespace vtkm::exec
#include <vtkm/exec/arg/FetchExtrude.h>
#endif

@ -52,6 +52,7 @@ set(headers
PointTransform.h
PolicyBase.h
PolicyDefault.h
PolicyExtrude.h
Probe.h
SplitSharpEdges.h
Streamline.h

@ -0,0 +1,45 @@
//=============================================================================
//
// 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 2012 Sandia Corporation.
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
//=============================================================================
#ifndef vtk_m_filter_PolicyExtrude_h
#define vtk_m_filter_PolicyExtrude_h
#include <vtkm/cont/ArrayHandleExtrudeCoords.h>
#include <vtkm/cont/CellSetExtrude.h>
#include <vtkm/ListTag.h>
#include <vtkm/filter/PolicyDefault.h>
struct VTKM_ALWAYS_EXPORT ExtrudeUnstructuredCellSets
: vtkm::ListTagBase<vtkm::cont::CellSetExtrude>
{
};
//Todo: add in Cylinder storage tag when it is written
struct VTKM_ALWAYS_EXPORT ExtrudeCoordinateStorage
: vtkm::ListTagBase<vtkm::cont::StorageTagBasic, vtkm::cont::internal::StorageTagExtrude>
{
};
struct VTKM_ALWAYS_EXPORT PolicyExtrude : vtkm::filter::PolicyBase<PolicyExtrude>
{
public:
using UnstructuredCellSetList = ExtrudeUnstructuredCellSets;
using AllCellSetList = ExtrudeUnstructuredCellSets;
using CoordinateStorageList = ExtrudeCoordinateStorage;
};
#endif

@ -26,11 +26,20 @@ public:
}
template <typename CellSetType>
void operator()(const CellSetType& cellset) const
void operator()(const CellSetType& vtkmNotUsed(cellset)) const
{
this->OutCellSet = Worklet.Run(cellset);
}
};
template <>
void DeduceCellSet::operator()(const vtkm::cont::CellSetExplicit<>& cellset) const
{
this->OutCellSet = Worklet.Run(cellset);
}
template <>
void DeduceCellSet::operator()(const vtkm::cont::CellSetStructured<3>& cellset) const
{
this->OutCellSet = Worklet.Run(cellset);
}
}
namespace vtkm

@ -60,6 +60,7 @@ set(headers
FunctionInterfaceDetailPost.h
FunctionInterfaceDetailPre.h
IndexTag.h
IndicesExtrude.h
Invocation.h
ListTagDetail.h
Unreachable.h

@ -0,0 +1,126 @@
#ifndef vtk_m_internal_IndicesExtrude_h
#define vtk_m_internal_IndicesExtrude_h
#include <vtkm/Math.h>
#include <vtkm/Types.h>
namespace vtkm
{
namespace exec
{
struct IndicesExtrude
{
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
IndicesExtrude() = default;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
IndicesExtrude(vtkm::Vec<vtkm::Int32, 3> pointIds1,
vtkm::Int32 plane1,
vtkm::Vec<vtkm::Int32, 3> pointIds2,
vtkm::Int32 plane2,
vtkm::Int32 numberOfPointsPerPlane)
: PointIds{ pointIds1, pointIds2 }
, Planes{ plane1, plane2 }
, NumberOfPointsPerPlane(numberOfPointsPerPlane)
{
}
VTKM_EXEC
vtkm::Id operator[](vtkm::IdComponent index) const
{
VTKM_ASSERT(index >= 0 && index < 6);
if (index < 3)
{
return (static_cast<vtkm::Id>(this->NumberOfPointsPerPlane) * this->Planes[0]) +
this->PointIds[0][index];
}
else
{
return (static_cast<vtkm::Id>(this->NumberOfPointsPerPlane) * this->Planes[1]) +
this->PointIds[1][index - 3];
}
}
VTKM_EXEC
constexpr vtkm::IdComponent GetNumberOfComponents() const { return 6; }
template <typename T, vtkm::IdComponent DestSize>
VTKM_EXEC void CopyInto(vtkm::Vec<T, DestSize>& dest) const
{
for (vtkm::IdComponent i = 0; i < vtkm::Min(6, DestSize); ++i)
{
dest[i] = (*this)[i];
}
}
vtkm::Vec<vtkm::Int32, 3> PointIds[2];
vtkm::Int32 Planes[2];
vtkm::Int32 NumberOfPointsPerPlane;
};
template <typename ConnectivityPortalType>
struct ReverseIndicesExtrude
{
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ReverseIndicesExtrude() = default;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ReverseIndicesExtrude(const ConnectivityPortalType conn,
vtkm::Id offset1,
vtkm::IdComponent length1,
vtkm::Id offset2,
vtkm::IdComponent length2,
vtkm::IdComponent plane1,
vtkm::IdComponent plane2,
vtkm::Int32 numberOfCellsPerPlane)
: Connectivity(conn)
, Offset1(offset1)
, Offset2(offset2)
, Length1(length1)
, NumberOfComponents(length1 + length2)
, CellOffset1(plane1 * numberOfCellsPerPlane)
, CellOffset2(plane2 * numberOfCellsPerPlane)
{
}
VTKM_EXEC
vtkm::Id operator[](vtkm::IdComponent index) const
{
VTKM_ASSERT(index >= 0 && index < (this->NumberOfComponents));
if (index < this->Length1)
{
return this->Connectivity.Get(this->Offset1 + index) + this->CellOffset1;
}
else
{
return this->Connectivity.Get(this->Offset2 + index - this->Length1) + this->CellOffset2;
}
}
VTKM_EXEC
vtkm::IdComponent GetNumberOfComponents() const { return this->NumberOfComponents; }
template <typename T, vtkm::IdComponent DestSize>
VTKM_EXEC void CopyInto(vtkm::Vec<T, DestSize>& dest) const
{
for (vtkm::IdComponent i = 0; i < vtkm::Min(this->NumberOfComponents, DestSize); ++i)
{
dest[i] = (*this)[i];
}
}
ConnectivityPortalType Connectivity;
vtkm::Id Offset1, Offset2;
vtkm::IdComponent Length1;
vtkm::IdComponent NumberOfComponents;
vtkm::Id CellOffset1, CellOffset2;
};
}
}
#endif //vtkm_m_internal_IndicesExtrude_h

@ -68,12 +68,14 @@ public:
}
VTKM_EXEC
void operator()(vtkm::CellShapeTagQuad shapeType, vtkm::Id& segments) const
void operator()(vtkm::CellShapeTagQuad vtkmNotUsed(shapeType), vtkm::Id& segments) const
{
if (shapeType.Id == vtkm::CELL_SHAPE_QUAD)
segments = 4;
else
segments = 0;
segments = 4;
}
VTKM_EXEC
void operator()(vtkm::CellShapeTagWedge vtkmNotUsed(shapeType), vtkm::Id& segments) const
{
segments = 24;
}
}; //class CountSegments
@ -279,7 +281,24 @@ public:
tri2seg(offset, cellIndices, cellId, 4, 5, 6, outputIndices);
tri2seg(offset, cellIndices, cellId, 4, 6, 7, outputIndices);
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
vtkm::CellShapeTagWedge vtkmNotUsed(shapeType),
const VecType& cellIndices,
const vtkm::Id& cellId,
OutputPortal& outputIndices) const
{
vtkm::Id offset = pointOffset;
tri2seg(offset, cellIndices, cellId, 0, 1, 2, outputIndices);
tri2seg(offset, cellIndices, cellId, 3, 5, 4, outputIndices);
tri2seg(offset, cellIndices, cellId, 3, 0, 2, outputIndices);
tri2seg(offset, cellIndices, cellId, 3, 2, 5, outputIndices);
tri2seg(offset, cellIndices, cellId, 1, 4, 5, outputIndices);
tri2seg(offset, cellIndices, cellId, 1, 5, 2, outputIndices);
tri2seg(offset, cellIndices, cellId, 0, 3, 4, outputIndices);
tri2seg(offset, cellIndices, cellId, 0, 4, 1, outputIndices);
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
vtkm::CellShapeTagGeneric shapeType,

@ -69,6 +69,11 @@ public:
else
quads = 0;
}
VTKM_EXEC
void operator()(vtkm::CellShapeTagWedge vtkmNotUsed(shapeType), vtkm::Id& quads) const
{
quads = 3;
}
}; //class CountQuads
template <int DIM>
@ -191,7 +196,19 @@ public:
outputIndices.Set(offset++, quad);
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
vtkm::CellShapeTagWedge vtkmNotUsed(shapeType),
const VecType& cellIndices,
const vtkm::Id& cellId,
OutputPortal& outputIndices) const
{
vtkm::Id offset = pointOffset;
cell2quad(offset, cellIndices, cellId, 3, 0, 2, 5, outputIndices);
cell2quad(offset, cellIndices, cellId, 1, 4, 5, 2, outputIndices);
cell2quad(offset, cellIndices, cellId, 0, 3, 4, 1, outputIndices);
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& offset,
vtkm::CellShapeTagQuad shapeType,

@ -71,6 +71,11 @@ public:
{
triangles = 2;
}
VTKM_EXEC
void operator()(vtkm::CellShapeTagWedge vtkmNotUsed(shapeType), vtkm::Id& triangles) const
{
triangles = 8;
}
}; //class CountTriangles
template <int DIM>
@ -271,6 +276,56 @@ public:
using ControlSignature = void(CellSetIn cellset, FieldInCell, WholeArrayOut);
using ExecutionSignature = void(_2, CellShape, PointIndices, WorkIndex, _3);
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& triangleOffset,
vtkm::CellShapeTagWedge vtkmNotUsed(shapeType),
const VecType& cellIndices,
const vtkm::Id& cellId,
OutputPortal& outputIndices) const
{
vtkm::Vec<vtkm::Id, 4> triangle;
triangle[1] = cellIndices[0];
triangle[2] = cellIndices[1];
triangle[3] = cellIndices[2];
triangle[0] = cellId;
outputIndices.Set(triangleOffset, triangle);
triangle[1] = cellIndices[3];
triangle[2] = cellIndices[5];
triangle[3] = cellIndices[4];
outputIndices.Set(triangleOffset + 1, triangle);
triangle[1] = cellIndices[3];
triangle[2] = cellIndices[0];
triangle[3] = cellIndices[2];
outputIndices.Set(triangleOffset + 2, triangle);
triangle[1] = cellIndices[3];
triangle[2] = cellIndices[2];
triangle[3] = cellIndices[5];
outputIndices.Set(triangleOffset + 3, triangle);
triangle[1] = cellIndices[1];
triangle[2] = cellIndices[4];
triangle[3] = cellIndices[5];
outputIndices.Set(triangleOffset + 4, triangle);
triangle[1] = cellIndices[1];
triangle[2] = cellIndices[5];
triangle[3] = cellIndices[2];
outputIndices.Set(triangleOffset + 5, triangle);
triangle[1] = cellIndices[0];
triangle[2] = cellIndices[3];
triangle[3] = cellIndices[4];
outputIndices.Set(triangleOffset + 6, triangle);
triangle[1] = cellIndices[0];
triangle[2] = cellIndices[4];
triangle[3] = cellIndices[1];
outputIndices.Set(triangleOffset + 7, triangle);
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& triangleOffset,
vtkm::CellShapeTagQuad vtkmNotUsed(shapeType),

@ -58,6 +58,11 @@ public:
{
points = 0;
}
VTKM_EXEC
void operator()(vtkm::CellShapeTagWedge vtkmNotUsed(shapeType), vtkm::Id& points) const
{
points = 0;
}
}; // ClassCountSegments
@ -79,6 +84,15 @@ public:
{
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
vtkm::CellShapeTagWedge vtkmNotUsed(shapeType),
const VecType& vtkmNotUsed(cellIndices),
const vtkm::Id& vtkmNotUsed(cellId),
OutputPortal& vtkmNotUsed(outputIndices)) const
{
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType),

@ -54,6 +54,11 @@ public:
{
points = 1;
}
VTKM_EXEC
void operator()(vtkm::CellShapeTagWedge vtkmNotUsed(shapeType), vtkm::Id& points) const
{
points = 0;
}
}; // ClassCountquads
@ -94,6 +99,15 @@ public:
{
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
vtkm::CellShapeTagWedge vtkmNotUsed(shapeType),
const VecType& vtkmNotUsed(cellIndices),
const vtkm::Id& vtkmNotUsed(cellId),
OutputPortal& vtkmNotUsed(outputIndices)) const
{
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& pointOffset,
vtkm::CellShapeTagHexahedron vtkmNotUsed(shapeType),

@ -53,6 +53,11 @@ public:
{
points = 0;
}
VTKM_EXEC
void operator()(vtkm::CellShapeTagWedge vtkmNotUsed(shapeType), vtkm::Id& points) const
{
points = 0;
}
}; // ClassCountPoints
@ -73,6 +78,14 @@ public:
OutputPortal& vtkmNotUsed(outputIndices)) const
{
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),
vtkm::CellShapeTagWedge vtkmNotUsed(shapeType),
const VecType& vtkmNotUsed(cellIndices),
const vtkm::Id& vtkmNotUsed(cellId),
OutputPortal& vtkmNotUsed(outputIndices)) const
{
}
template <typename VecType, typename OutputPortal>
VTKM_EXEC void operator()(const vtkm::Id& vtkmNotUsed(pointOffset),

@ -142,6 +142,15 @@ public:
{
}
template <typename IsoValuesType, typename FieldInType, typename NumTrianglesTablePortalType>
VTKM_EXEC void operator()(vtkm::CellShapeTagWedge vtkmNotUsed(shape),
const IsoValuesType& vtkmNotUsed(isovalues),
const FieldInType& vtkmNotUsed(fieldIn),
vtkm::IdComponent& vtkmNotUsed(numTriangles),
const NumTrianglesTablePortalType& vtkmNotUsed(numTrianglesTable)) const
{
}
template <typename IsoValuesType, typename FieldInType, typename NumTrianglesTablePortalType>
VTKM_EXEC void operator()(vtkm::CellShapeTagHexahedron vtkmNotUsed(shape),
const IsoValuesType& isovalues,
@ -330,6 +339,21 @@ public:
{ //covers when we have quads coming from 2d structured data
}
template <typename IsoValuesType,
typename FieldInType, // Vec-like, one per input point
typename IndicesVecType,
typename DeviceAdapter>
VTKM_EXEC void operator()(
CellShapeTagWedge vtkmNotUsed(shape),
const IsoValuesType& vtkmNotUsed(isovalues),
const FieldInType& vtkmNotUsed(fieldIn), // Input point field defining the contour
EdgeWeightGenerateMetaData::ExecObject<DeviceAdapter>& vtkmNotUsed(metaData),
vtkm::Id vtkmNotUsed(inputCellId),
vtkm::Id vtkmNotUsed(outputCellId),
vtkm::IdComponent vtkmNotUsed(visitIndex),
const IndicesVecType& vtkmNotUsed(indices)) const
{ //covers when we have quads coming from 2d structured data
}
template <typename IsoValuesType,
typename FieldInType, // Vec-like, one per input point
typename IndicesVecType,

@ -20,6 +20,7 @@
#include <vtkm/worklet/connectivities/InnerJoin.h>
#include <vtkm/worklet/connectivities/UnionFind.h>
namespace vtkm
{
namespace worklet

@ -102,37 +102,47 @@ public:
};
template <typename CellSetType>
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent>& outCellsPerCell)
vtkm::cont::CellSetSingleType<> Run(
const CellSetType& cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent>& vtkmNotUsed(outCellsPerCell))
{
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
// Input topology
auto inShapes =
cellSet.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
auto inNumIndices =
cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
// Output topology
vtkm::cont::ArrayHandle<vtkm::Id> outConnectivity;
vtkm::worklet::internal::TetrahedralizeTables tables;
// Determine the number of output cells each input cell will generate
vtkm::worklet::DispatcherMapField<TetrahedraPerCell> tetPerCellDispatcher;
tetPerCellDispatcher.Invoke(inShapes, tables.PrepareForInput(), outCellsPerCell);
// Build new cells
vtkm::worklet::DispatcherMapTopology<TetrahedralizeCell> tetrahedralizeDispatcher(
TetrahedralizeCell::MakeScatter(outCellsPerCell));
tetrahedralizeDispatcher.Invoke(
cellSet, tables.PrepareForInput(), vtkm::cont::make_ArrayHandleGroupVec<4>(outConnectivity));
// Add cells to output cellset
outCellSet.Fill(cellSet.GetNumberOfPoints(), vtkm::CellShapeTagTetra::Id, 4, outConnectivity);
return outCellSet;
}
};
template <>
vtkm::cont::CellSetSingleType<> TetrahedralizeExplicit::Run(
const vtkm::cont::CellSetExplicit<>& cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent>& outCellsPerCell)
{
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
// Input topology
auto inShapes =
cellSet.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
auto inNumIndices =
cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
// Output topology
vtkm::cont::ArrayHandle<vtkm::Id> outConnectivity;
vtkm::worklet::internal::TetrahedralizeTables tables;
// Determine the number of output cells each input cell will generate
vtkm::worklet::DispatcherMapField<TetrahedraPerCell> tetPerCellDispatcher;
tetPerCellDispatcher.Invoke(inShapes, tables.PrepareForInput(), outCellsPerCell);
// Build new cells
vtkm::worklet::DispatcherMapTopology<TetrahedralizeCell> tetrahedralizeDispatcher(
TetrahedralizeCell::MakeScatter(outCellsPerCell));
tetrahedralizeDispatcher.Invoke(
cellSet, tables.PrepareForInput(), vtkm::cont::make_ArrayHandleGroupVec<4>(outConnectivity));
// Add cells to output cellset
outCellSet.Fill(cellSet.GetNumberOfPoints(), vtkm::CellShapeTagTetra::Id, 4, outConnectivity);
return outCellSet;
}
}
} // namespace vtkm::worklet

@ -101,40 +101,46 @@ public:
connectivityOut[2] = connectivityIn[triIndices[2]];
}
};
template <typename CellSetType>
vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent>& outCellsPerCell)
{
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
// Input topology
auto inShapes =
cellSet.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
auto inNumIndices =
cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
// Output topology
vtkm::cont::ArrayHandle<vtkm::Id> outConnectivity;
vtkm::worklet::internal::TriangulateTables tables;
// Determine the number of output cells each input cell will generate
vtkm::worklet::DispatcherMapField<TrianglesPerCell> triPerCellDispatcher;
triPerCellDispatcher.Invoke(inShapes, inNumIndices, tables.PrepareForInput(), outCellsPerCell);
// Build new cells
vtkm::worklet::DispatcherMapTopology<TriangulateCell> triangulateDispatcher(
TriangulateCell::MakeScatter(outCellsPerCell));
triangulateDispatcher.Invoke(
cellSet, tables.PrepareForInput(), vtkm::cont::make_ArrayHandleGroupVec<3>(outConnectivity));
// Add cells to output cellset
outCellSet.Fill(
cellSet.GetNumberOfPoints(), vtkm::CellShapeTagTriangle::Id, 3, outConnectivity);
return outCellSet;
}
};
template <>
vtkm::cont::CellSetSingleType<> TriangulateExplicit::Run(
const vtkm::cont::CellSetExplicit<>& cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent>& outCellsPerCell)
{
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
// Input topology
auto inShapes =
cellSet.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
auto inNumIndices =
cellSet.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
// Output topology
vtkm::cont::ArrayHandle<vtkm::Id> outConnectivity;
vtkm::worklet::internal::TriangulateTables tables;
// Determine the number of output cells each input cell will generate
vtkm::worklet::DispatcherMapField<TrianglesPerCell> triPerCellDispatcher;
triPerCellDispatcher.Invoke(inShapes, inNumIndices, tables.PrepareForInput(), outCellsPerCell);
// Build new cells
vtkm::worklet::DispatcherMapTopology<TriangulateCell> triangulateDispatcher(
TriangulateCell::MakeScatter(outCellsPerCell));
triangulateDispatcher.Invoke(
cellSet, tables.PrepareForInput(), vtkm::cont::make_ArrayHandleGroupVec<3>(outConnectivity));
// Add cells to output cellset
outCellSet.Fill(cellSet.GetNumberOfPoints(), vtkm::CellShapeTagTriangle::Id, 3, outConnectivity);
return outCellSet;
}
}
} // namespace vtkm::worklet