vtk-m2/vtkm/cont/CellSetExplicit.h

584 lines
22 KiB
C
Raw Normal View History

//============================================================================
// 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.
//============================================================================
2015-04-15 16:43:12 +00:00
#ifndef vtk_m_cont_CellSetExplicit_h
#define vtk_m_cont_CellSetExplicit_h
#include <vtkm/CellShape.h>
2017-05-18 14:51:24 +00:00
#include <vtkm/TopologyElementTag.h>
2015-04-15 16:43:12 +00:00
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
#include <vtkm/exec/ConnectivityExplicit.h>
2015-04-15 16:43:12 +00:00
2015-10-30 19:59:36 +00:00
#include <vtkm/cont/ArrayHandleConstant.h>
2017-05-18 14:51:24 +00:00
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
2015-10-30 19:59:36 +00:00
#include <map>
#include <utility>
2017-05-18 14:29:41 +00:00
namespace vtkm
{
namespace cont
{
2015-04-15 16:43:12 +00:00
2017-05-18 14:29:41 +00:00
namespace detail
{
2017-05-18 14:29:41 +00:00
template <typename CellSetType, typename FromTopology, typename ToTopology>
struct CellSetExplicitConnectivityChooser
{
2017-05-18 14:29:41 +00:00
typedef vtkm::cont::internal::ConnectivityExplicitInternals<> ConnectivityType;
};
} // namespace detail
#ifndef VTKM_DEFAULT_SHAPE_STORAGE_TAG
#define VTKM_DEFAULT_SHAPE_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#endif
#ifndef VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG
#define VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#endif
#ifndef VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG
#define VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#endif
#ifndef VTKM_DEFAULT_OFFSETS_STORAGE_TAG
#define VTKM_DEFAULT_OFFSETS_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#endif
2017-05-18 14:29:41 +00:00
template <typename ShapeStorageTag = VTKM_DEFAULT_SHAPE_STORAGE_TAG,
typename NumIndicesStorageTag = VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG,
typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
typename OffsetsStorageTag = VTKM_DEFAULT_OFFSETS_STORAGE_TAG>
class VTKM_ALWAYS_EXPORT CellSetExplicit : public CellSet
2015-04-15 16:43:12 +00:00
{
typedef CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
2017-05-18 14:29:41 +00:00
OffsetsStorageTag>
Thisclass;
2017-05-18 14:29:41 +00:00
template <typename FromTopology, typename ToTopology>
struct ConnectivityChooser
{
typedef
typename detail::CellSetExplicitConnectivityChooser<Thisclass, FromTopology, ToTopology>::
ConnectivityType ConnectivityType;
typedef typename ConnectivityType::ShapeArrayType ShapeArrayType;
typedef typename ConnectivityType::NumIndicesArrayType NumIndicesArrayType;
typedef typename ConnectivityType::ConnectivityArrayType ConnectivityArrayType;
typedef typename ConnectivityType::IndexOffsetArrayType IndexOffsetArrayType;
};
2015-05-12 13:39:00 +00:00
public:
typedef vtkm::Id SchedulingRangeType;
2015-05-12 13:39:00 +00:00
//point to cell is used when iterating cells and asking for point properties
2017-05-18 14:29:41 +00:00
typedef ConnectivityChooser<vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell>
PointToCellConnectivityType;
typedef typename PointToCellConnectivityType::ShapeArrayType ShapeArrayType;
typedef typename PointToCellConnectivityType::NumIndicesArrayType NumIndicesArrayType;
typedef typename PointToCellConnectivityType::ConnectivityArrayType ConnectivityArrayType;
typedef typename PointToCellConnectivityType::IndexOffsetArrayType IndexOffsetArrayType;
VTKM_CONT
2017-05-18 14:29:41 +00:00
CellSetExplicit(const std::string& name = std::string())
: CellSet(name)
, ConnectivityAdded(-1)
, NumberOfCellsAdded(-1)
, NumberOfPoints(0)
{
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
CellSetExplicit(const Thisclass& src)
: CellSet(src)
, PointToCell(src.PointToCell)
, CellToPoint(src.CellToPoint)
, ConnectivityAdded(src.ConnectivityAdded)
, NumberOfCellsAdded(src.NumberOfCellsAdded)
, NumberOfPoints(src.NumberOfPoints)
{
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
Thisclass& operator=(const Thisclass& src)
{
this->CellSet::operator=(src);
this->PointToCell = src.PointToCell;
this->CellToPoint = src.CellToPoint;
this->ConnectivityAdded = src.ConnectivityAdded;
this->NumberOfCellsAdded = src.NumberOfCellsAdded;
this->NumberOfPoints = src.NumberOfPoints;
return *this;
}
2017-05-18 14:29:41 +00:00
virtual ~CellSetExplicit() {}
vtkm::Id GetNumberOfCells() const VTKM_OVERRIDE
2015-05-12 13:39:00 +00:00
{
return this->PointToCell.GetNumberOfElements();
2015-05-12 13:39:00 +00:00
}
2017-05-18 14:29:41 +00:00
vtkm::Id GetNumberOfPoints() const VTKM_OVERRIDE { return this->NumberOfPoints; }
vtkm::Id GetNumberOfFaces() const VTKM_OVERRIDE { return -1; }
vtkm::Id GetNumberOfEdges() const VTKM_OVERRIDE { return -1; }
VTKM_CONT
vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagCell) const
{
return this->GetNumberOfCells();
}
VTKM_CONT
vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagPoint) const
{
return this->GetNumberOfPoints();
}
VTKM_CONT
vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellIndex) const
{
return this->PointToCell.NumIndices.GetPortalConstControl().Get(cellIndex);
}
VTKM_CONT
vtkm::UInt8 GetCellShape(vtkm::Id cellIndex) const
{
return this->PointToCell.Shapes.GetPortalConstControl().Get(cellIndex);
}
2015-11-02 18:05:12 +00:00
template <vtkm::IdComponent ItemTupleLength>
2017-05-18 14:29:41 +00:00
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::Vec<vtkm::Id, ItemTupleLength>& ids) const
{
2015-11-02 18:05:12 +00:00
this->PointToCell.BuildIndexOffsets(VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
vtkm::IdComponent numIndices = this->GetNumberOfPointsInCell(index);
2017-05-18 14:29:41 +00:00
vtkm::Id start = this->PointToCell.IndexOffsets.GetPortalConstControl().Get(index);
for (vtkm::IdComponent i = 0; i < numIndices && i < ItemTupleLength; i++)
ids[i] = this->PointToCell.Connectivity.GetPortalConstControl().Get(start + i);
}
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::cont::ArrayHandle<vtkm::Id>& ids) const
{
this->PointToCell.BuildIndexOffsets(VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
vtkm::IdComponent numIndices = this->GetNumberOfPointsInCell(index);
ids.Allocate(numIndices);
vtkm::Id start = this->PointToCell.IndexOffsets.GetPortalConstControl().Get(index);
vtkm::cont::ArrayHandle<vtkm::Id>::PortalControl idPortal = ids.GetPortalControl();
auto PtCellPortal = this->PointToCell.Connectivity.GetPortalConstControl();
for (vtkm::IdComponent i = 0; i < numIndices && i < numIndices; i++)
idPortal.Set(i, PtCellPortal.Get(start + i));
}
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::cont::ArrayHandle<vtkm::Id>& ids) const
{
this->PointToCell.BuildIndexOffsets(VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
vtkm::IdComponent numIndices = this->GetNumberOfPointsInCell(index);
ids.Allocate(numIndices);
vtkm::Id start = this->PointToCell.IndexOffsets.GetPortalConstControl().Get(index);
vtkm::cont::ArrayHandle<vtkm::Id>::PortalControl idPortal = ids.GetPortalControl();
auto PtCellPortal = this->PointToCell.Connectivity.GetPortalConstControl();
for (vtkm::IdComponent i = 0; i < numIndices && i < numIndices; i++)
idPortal.Set(i, PtCellPortal.Get(start + i));
}
/// First method to add cells -- one at a time.
VTKM_CONT
void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen)
{
this->PointToCell.Shapes.Allocate(numCells);
this->PointToCell.NumIndices.Allocate(numCells);
this->PointToCell.Connectivity.Allocate(connectivityMaxLen);
this->PointToCell.IndexOffsets.Allocate(numCells);
this->NumberOfCellsAdded = 0;
this->ConnectivityAdded = 0;
}
template <typename IdVecType>
2017-05-18 14:29:41 +00:00
VTKM_CONT void AddCell(vtkm::UInt8 cellType, vtkm::IdComponent numVertices, const IdVecType& ids)
{
using Traits = vtkm::VecTraits<IdVecType>;
2017-05-18 14:29:41 +00:00
VTKM_STATIC_ASSERT_MSG((std::is_same<typename Traits::ComponentType, vtkm::Id>::value),
"CellSetSingleType::AddCell requires vtkm::Id for indices.");
if (Traits::GetNumberOfComponents(ids) < numVertices)
{
2017-05-18 14:29:41 +00:00
throw vtkm::cont::ErrorBadValue("Not enough indices given to CellSetSingleType::AddCell.");
}
if (this->NumberOfCellsAdded >= this->PointToCell.Shapes.GetNumberOfValues())
{
2017-05-18 14:29:41 +00:00
throw vtkm::cont::ErrorBadValue("Added more cells then expected.");
}
2017-05-18 14:29:41 +00:00
if (this->ConnectivityAdded + numVertices > this->PointToCell.Connectivity.GetNumberOfValues())
{
throw vtkm::cont::ErrorBadValue(
2017-05-18 14:29:41 +00:00
"Connectivity increased passed estimated maximum connectivity.");
}
this->PointToCell.Shapes.GetPortalControl().Set(this->NumberOfCellsAdded, cellType);
this->PointToCell.NumIndices.GetPortalControl().Set(this->NumberOfCellsAdded, numVertices);
2017-05-18 14:29:41 +00:00
for (vtkm::IdComponent iVec = 0; iVec < numVertices; ++iVec)
{
2017-05-18 14:29:41 +00:00
this->PointToCell.Connectivity.GetPortalControl().Set(this->ConnectivityAdded + iVec,
Traits::GetComponent(ids, iVec));
}
2017-05-18 14:29:41 +00:00
this->PointToCell.IndexOffsets.GetPortalControl().Set(this->NumberOfCellsAdded,
this->ConnectivityAdded);
this->NumberOfCellsAdded++;
this->ConnectivityAdded += numVertices;
}
VTKM_CONT
void CompleteAddingCells(vtkm::Id numPoints)
{
this->NumberOfPoints = numPoints;
this->PointToCell.Connectivity.Shrink(ConnectivityAdded);
this->PointToCell.ElementsValid = true;
this->PointToCell.IndexOffsetsValid = true;
if (this->NumberOfCellsAdded != this->GetNumberOfCells())
{
2017-05-18 14:29:41 +00:00
throw vtkm::cont::ErrorBadValue("Did not add as many cells as expected.");
}
this->NumberOfCellsAdded = -1;
this->ConnectivityAdded = -1;
}
/// Second method to add cells -- all at once.
/// Assigns the array handles to the explicit connectivity. This is
/// the way you can fill the memory from another system without copying
VTKM_CONT
void Fill(vtkm::Id numPoints,
2017-05-18 14:29:41 +00:00
const vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorageTag>& cellTypes,
const vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>& numIndices,
const vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>& connectivity,
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsets =
vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>())
2015-05-15 17:15:11 +00:00
{
this->NumberOfPoints = numPoints;
this->PointToCell.Shapes = cellTypes;
this->PointToCell.NumIndices = numIndices;
this->PointToCell.Connectivity = connectivity;
this->PointToCell.ElementsValid = true;
2017-05-18 14:29:41 +00:00
if (offsets.GetNumberOfValues() == cellTypes.GetNumberOfValues())
2015-09-25 15:45:09 +00:00
{
this->PointToCell.IndexOffsets = offsets;
this->PointToCell.IndexOffsetsValid = true;
2015-09-25 15:45:09 +00:00
}
else
2015-09-25 15:45:09 +00:00
{
this->PointToCell.IndexOffsetsValid = false;
2015-09-25 15:45:09 +00:00
if (offsets.GetNumberOfValues() != 0)
{
2017-05-18 14:29:41 +00:00
throw vtkm::cont::ErrorBadValue("Explicit cell offsets array unexpected size. "
"Use an empty array to automatically generate.");
}
2015-09-25 15:45:09 +00:00
}
}
template <typename DeviceAdapter, typename FromTopology, typename ToTopology>
struct ExecutionTypes
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapter);
VTKM_IS_TOPOLOGY_ELEMENT_TAG(FromTopology);
VTKM_IS_TOPOLOGY_ELEMENT_TAG(ToTopology);
2017-05-18 14:29:41 +00:00
typedef ConnectivityChooser<FromTopology, ToTopology> ConnectivityTypes;
2017-05-18 14:29:41 +00:00
typedef typename ConnectivityTypes::ShapeArrayType::template ExecutionTypes<
DeviceAdapter>::PortalConst ShapePortalType;
typedef typename ConnectivityTypes::NumIndicesArrayType::template ExecutionTypes<
DeviceAdapter>::PortalConst IndicePortalType;
typedef typename ConnectivityTypes::ConnectivityArrayType::template ExecutionTypes<
DeviceAdapter>::PortalConst ConnectivityPortalType;
typedef typename ConnectivityTypes::IndexOffsetArrayType::template ExecutionTypes<
DeviceAdapter>::PortalConst IndexOffsetPortalType;
typedef vtkm::exec::ConnectivityExplicit<ShapePortalType,
IndicePortalType,
ConnectivityPortalType,
IndexOffsetPortalType>
2017-05-18 14:29:41 +00:00
ExecObjectType;
};
2017-05-18 14:29:41 +00:00
template <typename Device, typename FromTopology, typename ToTopology>
typename ExecutionTypes<Device, FromTopology, ToTopology>::ExecObjectType
PrepareForInput(Device, FromTopology, ToTopology) const
{
2015-10-30 19:59:36 +00:00
this->BuildConnectivity(Device(), FromTopology(), ToTopology());
2017-05-18 14:29:41 +00:00
const typename ConnectivityChooser<FromTopology, ToTopology>::ConnectivityType& connectivity =
this->GetConnectivity(FromTopology(), ToTopology());
VTKM_ASSERT(connectivity.ElementsValid);
2017-05-18 14:29:41 +00:00
typedef typename ExecutionTypes<Device, FromTopology, ToTopology>::ExecObjectType ExecObjType;
return ExecObjType(connectivity.Shapes.PrepareForInput(Device()),
connectivity.NumIndices.PrepareForInput(Device()),
connectivity.Connectivity.PrepareForInput(Device()),
connectivity.IndexOffsets.PrepareForInput(Device()));
2015-05-15 17:15:11 +00:00
}
2017-05-18 14:29:41 +00:00
template <typename Device, typename FromTopology, typename ToTopology>
VTKM_CONT void BuildConnectivity(Device, FromTopology, ToTopology) const
{
typedef CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
2017-05-18 14:29:41 +00:00
OffsetsStorageTag>
CSE;
2017-05-18 14:29:41 +00:00
CSE* self = const_cast<CSE*>(this);
2015-10-30 19:59:36 +00:00
self->CreateConnectivity(Device(), FromTopology(), ToTopology());
2017-05-18 14:29:41 +00:00
self->GetConnectivity(FromTopology(), ToTopology()).BuildIndexOffsets(Device());
}
2017-05-18 14:29:41 +00:00
template <typename Device>
VTKM_CONT void CreateConnectivity(Device,
vtkm::TopologyElementTagPoint,
2017-05-18 14:29:41 +00:00
vtkm::TopologyElementTagCell)
{
// nothing to do
}
2015-10-30 19:59:36 +00:00
// Worklet to expand the PointToCell numIndices array by repeating cell index
class ExpandIndices : public vtkm::worklet::WorkletMapField
{
2015-10-30 19:59:36 +00:00
public:
typedef void ControlSignature(FieldIn<> cellIndex,
FieldIn<> offset,
FieldIn<> numIndices,
WholeArrayOut<> cellIndices);
2017-05-18 14:29:41 +00:00
typedef void ExecutionSignature(_1, _2, _3, _4);
2015-10-30 19:59:36 +00:00
typedef _1 InputDomain;
VTKM_CONT
2015-10-30 19:59:36 +00:00
ExpandIndices() {}
2017-05-18 14:29:41 +00:00
template <typename PortalType>
VTKM_EXEC void operator()(const vtkm::Id& cellIndex,
const vtkm::Id& offset,
const vtkm::Id& numIndices,
const PortalType& cellIndices) const
{
VTKM_ASSERT(cellIndices.GetNumberOfValues() >= offset + numIndices);
2015-10-30 19:59:36 +00:00
vtkm::Id startIndex = offset;
for (vtkm::Id i = 0; i < numIndices; i++)
{
2015-10-30 19:59:36 +00:00
cellIndices.Set(startIndex++, cellIndex);
}
}
2015-10-30 19:59:36 +00:00
};
2017-05-18 14:29:41 +00:00
template <typename Device>
VTKM_CONT void CreateConnectivity(Device,
vtkm::TopologyElementTagCell,
2017-05-18 14:29:41 +00:00
vtkm::TopologyElementTagPoint)
2015-10-30 19:59:36 +00:00
{
// PointToCell connectivity array (point indices) will be
// transformed into the CellToPoint numIndices array using reduction
//
// PointToCell numIndices array using expansion will be
// transformed into the CellToPoint connectivity array
2015-10-30 19:59:36 +00:00
if (this->CellToPoint.ElementsValid)
{
2015-10-30 19:59:36 +00:00
return;
}
2015-10-30 19:59:36 +00:00
typedef vtkm::cont::DeviceAdapterAlgorithm<Device> Algorithm;
2015-10-30 19:59:36 +00:00
// Sizes of the PointToCell information
2015-11-02 18:05:12 +00:00
vtkm::Id numberOfCells = this->GetNumberOfCells();
vtkm::Id connectivityLength = this->PointToCell.Connectivity.GetNumberOfValues();
2015-10-30 19:59:36 +00:00
// PointToCell connectivity will be basis of CellToPoint numIndices
vtkm::cont::ArrayHandle<vtkm::Id> pointIndices;
Algorithm::Copy(this->PointToCell.Connectivity, pointIndices);
2015-10-30 19:59:36 +00:00
// PointToCell numIndices will be basis of CellToPoint connectivity
this->CellToPoint.Connectivity.Allocate(connectivityLength);
2015-10-30 19:59:36 +00:00
vtkm::cont::ArrayHandleCounting<vtkm::Id> index(0, 1, numberOfCells);
this->PointToCell.BuildIndexOffsets(Device());
vtkm::worklet::DispatcherMapField<ExpandIndices, Device> expandDispatcher;
expandDispatcher.Invoke(index,
this->PointToCell.IndexOffsets,
this->PointToCell.NumIndices,
this->CellToPoint.Connectivity);
2015-10-30 19:59:36 +00:00
// SortByKey where key is PointToCell connectivity and value is the expanded cellIndex
Algorithm::SortByKey(pointIndices, this->CellToPoint.Connectivity);
if (this->GetNumberOfPoints() <= 0 && connectivityLength > 0)
{
2015-10-30 19:59:36 +00:00
this->NumberOfPoints = pointIndices.GetPortalControl().Get(connectivityLength - 1) + 1;
}
vtkm::Id numberOfPoints = this->GetNumberOfPoints();
2015-10-30 19:59:36 +00:00
// CellToPoint numIndices from the now sorted PointToCell connectivity
vtkm::cont::ArrayHandleConstant<vtkm::Id> numArray(1, connectivityLength);
vtkm::cont::ArrayHandle<vtkm::Id> uniquePoints;
vtkm::cont::ArrayHandle<vtkm::Id> numIndices;
uniquePoints.Allocate(numberOfPoints);
numIndices.Allocate(numberOfPoints);
2017-05-18 14:29:41 +00:00
Algorithm::ReduceByKey(pointIndices, numArray, uniquePoints, numIndices, vtkm::Add());
2015-10-30 19:59:36 +00:00
// Set the CellToPoint information
this->CellToPoint.Shapes = vtkm::cont::make_ArrayHandleConstant(
static_cast<vtkm::UInt8>(CELL_SHAPE_VERTEX), numberOfPoints);
2015-10-30 19:59:36 +00:00
Algorithm::Copy(numIndices, this->CellToPoint.NumIndices);
this->CellToPoint.ElementsValid = true;
this->CellToPoint.IndexOffsetsValid = false;
}
2017-05-18 14:29:41 +00:00
void PrintSummary(std::ostream& out) const VTKM_OVERRIDE
2015-05-20 19:26:10 +00:00
{
out << " ExplicitCellSet: " << this->Name << std::endl;
out << " PointToCell: " << std::endl;
this->PointToCell.PrintSummary(out);
out << " CellToPoint: " << std::endl;
this->CellToPoint.PrintSummary(out);
}
2017-05-18 14:29:41 +00:00
template <typename FromTopology, typename ToTopology>
VTKM_CONT const typename ConnectivityChooser<FromTopology, ToTopology>::ShapeArrayType&
GetShapesArray(FromTopology, ToTopology) const
{
return this->GetConnectivity(FromTopology(), ToTopology()).Shapes;
}
2017-05-18 14:29:41 +00:00
template <typename FromTopology, typename ToTopology>
VTKM_CONT const typename ConnectivityChooser<FromTopology, ToTopology>::NumIndicesArrayType&
GetNumIndicesArray(FromTopology, ToTopology) const
{
return this->GetConnectivity(FromTopology(), ToTopology()).NumIndices;
}
2017-05-18 14:29:41 +00:00
template <typename FromTopology, typename ToTopology>
VTKM_CONT const typename ConnectivityChooser<FromTopology, ToTopology>::ConnectivityArrayType&
GetConnectivityArray(FromTopology, ToTopology) const
{
return this->GetConnectivity(FromTopology(), ToTopology()).Connectivity;
}
2017-05-18 14:29:41 +00:00
template <typename FromTopology, typename ToTopology>
VTKM_CONT const typename ConnectivityChooser<FromTopology, ToTopology>::IndexOffsetArrayType&
GetIndexOffsetArray(FromTopology, ToTopology) const
{
return this->GetConnectivity(FromTopology(), ToTopology()).IndexOffsets;
2015-05-20 19:26:10 +00:00
}
protected:
2017-05-18 14:29:41 +00:00
typename ConnectivityChooser<vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell>::ConnectivityType PointToCell;
// TODO: Actually implement CellToPoint and other connectivity. (That is,
// derive the connectivity from PointToCell.
2017-05-18 14:29:41 +00:00
typename ConnectivityChooser<vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint>::ConnectivityType CellToPoint;
2017-05-18 14:29:41 +00:00
private:
// A set of overloaded methods to get the connectivity from a pair of
// topology element types.
#define VTKM_GET_CONNECTIVITY_METHOD(FromTopology, ToTopology, Ivar) \
VTKM_CONT \
const typename ConnectivityChooser<FromTopology, ToTopology>::ConnectivityType& GetConnectivity( \
FromTopology, ToTopology) const \
{ \
return this->Ivar; \
} \
VTKM_CONT \
typename ConnectivityChooser<FromTopology, ToTopology>::ConnectivityType& GetConnectivity( \
FromTopology, ToTopology) \
{ \
return this->Ivar; \
}
VTKM_GET_CONNECTIVITY_METHOD(vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell,
PointToCell)
VTKM_GET_CONNECTIVITY_METHOD(vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint,
CellToPoint)
#undef VTKM_GET_CONNECTIVITY_METHOD
protected:
// These are used in the AddCell and related methods to incrementally add
// cells. They need to be protected as subclasses of CellSetExplicit
// need to set these values when implementing Fill()
vtkm::Id ConnectivityAdded;
vtkm::Id NumberOfCellsAdded;
vtkm::Id NumberOfPoints;
2015-04-15 16:43:12 +00:00
};
2017-05-18 14:29:41 +00:00
namespace detail
{
2017-05-18 14:29:41 +00:00
template <typename Storage1, typename Storage2, typename Storage3, typename Storage4>
struct CellSetExplicitConnectivityChooser<
2017-05-18 14:29:41 +00:00
vtkm::cont::CellSetExplicit<Storage1, Storage2, Storage3, Storage4>,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell>
{
typedef vtkm::cont::internal::
ConnectivityExplicitInternals<Storage1, Storage2, Storage3, Storage4>
ConnectivityType;
};
2017-05-18 14:29:41 +00:00
template <typename CellSetType>
struct CellSetExplicitConnectivityChooser<CellSetType,
vtkm::TopologyElementTagCell,
2017-05-18 14:29:41 +00:00
vtkm::TopologyElementTagPoint>
{
//only specify the shape type as it will be constant as everything
//is a vertex. otherwise use the defaults.
typedef vtkm::cont::internal::ConnectivityExplicitInternals<
2017-05-18 14:29:41 +00:00
typename ArrayHandleConstant<vtkm::UInt8>::StorageTag>
ConnectivityType;
};
} // namespace detail
2015-04-15 16:43:12 +00:00
}
} // namespace vtkm::cont
#endif //vtk_m_cont_CellSetExplicit_h