//============================================================================ // 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. //============================================================================ #ifndef vtk_m_cont_CellSetExplicit_h #define vtk_m_cont_CellSetExplicit_h #include #include #include #include #include #include #include #include #include #include #include #include #include namespace vtkm { namespace cont { namespace detail { template struct CellSetExplicitConnectivityChooser { using ConnectivityType = vtkm::cont::internal::ConnectivityExplicitInternals<>; }; // The connectivity generally used for the visit-points-with-cells connectivity. // This type of connectivity does not have variable shape types, and since it is // never really provided externally we can use the defaults for the other arrays. using DefaultVisitPointsWithCellsConnectivityExplicit = vtkm::cont::internal::ConnectivityExplicitInternals< typename ArrayHandleConstant::StorageTag>; VTKM_CONT_EXPORT void BuildReverseConnectivity( const vtkm::cont::UnknownArrayHandle& connections, const vtkm::cont::UnknownArrayHandle& offsets, vtkm::Id numberOfPoints, vtkm::cont::detail::DefaultVisitPointsWithCellsConnectivityExplicit& visitPointsWithCells, vtkm::cont::DeviceAdapterId device); } // namespace detail #ifndef VTKM_DEFAULT_SHAPES_STORAGE_TAG #define VTKM_DEFAULT_SHAPES_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 template class VTKM_ALWAYS_EXPORT CellSetExplicit : public CellSet { using Thisclass = CellSetExplicit; template struct ConnectivityChooser { private: using Chooser = typename detail:: CellSetExplicitConnectivityChooser; public: using ConnectivityType = typename Chooser::ConnectivityType; using ShapesArrayType = typename ConnectivityType::ShapesArrayType; using ConnectivityArrayType = typename ConnectivityType::ConnectivityArrayType; using OffsetsArrayType = typename ConnectivityType::OffsetsArrayType; using NumIndicesArrayType = vtkm::cont::ArrayHandleOffsetsToNumComponents; using ExecConnectivityType = vtkm::exec::ConnectivityExplicit; }; using ConnTypes = ConnectivityChooser; using RConnTypes = ConnectivityChooser; using CellPointIdsType = typename ConnTypes::ConnectivityType; using PointCellIdsType = typename RConnTypes::ConnectivityType; public: using SchedulingRangeType = vtkm::Id; using ShapesArrayType = typename CellPointIdsType::ShapesArrayType; using ConnectivityArrayType = typename CellPointIdsType::ConnectivityArrayType; using OffsetsArrayType = typename CellPointIdsType::OffsetsArrayType; using NumIndicesArrayType = typename ConnTypes::NumIndicesArrayType; VTKM_CONT CellSetExplicit(); VTKM_CONT CellSetExplicit(const Thisclass& src); VTKM_CONT CellSetExplicit(Thisclass&& src) noexcept; VTKM_CONT Thisclass& operator=(const Thisclass& src); VTKM_CONT Thisclass& operator=(Thisclass&& src) noexcept; VTKM_CONT virtual ~CellSetExplicit() override; VTKM_CONT vtkm::Id GetNumberOfCells() const override; VTKM_CONT vtkm::Id GetNumberOfPoints() const override; VTKM_CONT vtkm::Id GetNumberOfFaces() const override; VTKM_CONT vtkm::Id GetNumberOfEdges() const override; VTKM_CONT void PrintSummary(std::ostream& out) const override; VTKM_CONT void ReleaseResourcesExecution() override; VTKM_CONT std::shared_ptr NewInstance() const override; VTKM_CONT void DeepCopy(const CellSet* src) override; VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagCell) const; VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagPoint) const; VTKM_CONT vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellid) const override; VTKM_CONT void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override; VTKM_CONT typename vtkm::cont::ArrayHandle::ReadPortalType ShapesReadPortal() const; VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id cellid) const override; template VTKM_CONT void GetIndices(vtkm::Id index, vtkm::Vec& ids) const; VTKM_CONT void GetIndices(vtkm::Id index, vtkm::cont::ArrayHandle& ids) const; /// First method to add cells -- one at a time. VTKM_CONT void PrepareToAddCells(vtkm::Id numCells, vtkm::Id connectivityMaxLen); template VTKM_CONT void AddCell(vtkm::UInt8 cellType, vtkm::IdComponent numVertices, const IdVecType& ids); VTKM_CONT void CompleteAddingCells(vtkm::Id numPoints); /// 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, const vtkm::cont::ArrayHandle& cellTypes, const vtkm::cont::ArrayHandle& connectivity, const vtkm::cont::ArrayHandle& offsets); template struct VTKM_DEPRECATED( 1.6, "Replace ExecutionTypes::ExecObjectType with ExecConnectivityType.") ExecutionTypes { private: VTKM_IS_DEVICE_ADAPTER_TAG(Device); VTKM_IS_TOPOLOGY_ELEMENT_TAG(VisitTopology); VTKM_IS_TOPOLOGY_ELEMENT_TAG(IncidentTopology); using Chooser = ConnectivityChooser; using ShapesAT = typename Chooser::ShapesArrayType; using ConnAT = typename Chooser::ConnectivityArrayType; using OffsetsAT = typename Chooser::OffsetsArrayType; public: using ShapesPortalType = typename ShapesAT::ReadPortalType; using ConnectivityPortalType = typename ConnAT::ReadPortalType; using OffsetsPortalType = typename OffsetsAT::ReadPortalType; using ExecObjectType = vtkm::exec::ConnectivityExplicit; }; template using ExecConnectivityType = typename ConnectivityChooser::ExecConnectivityType; template VTKM_CONT ExecConnectivityType PrepareForInput( vtkm::cont::DeviceAdapterId, VisitTopology, IncidentTopology, vtkm::cont::Token&) const; template VTKM_DEPRECATED(1.6, "Provide a vtkm::cont::Token object when calling PrepareForInput.") VTKM_CONT ExecConnectivityType PrepareForInput( vtkm::cont::DeviceAdapterId device, VisitTopology visitTopology, IncidentTopology incidentTopology) const { vtkm::cont::Token token; return this->PrepareForInput(device, visitTopology, incidentTopology, token); } template VTKM_CONT const typename ConnectivityChooser::ShapesArrayType& GetShapesArray(VisitTopology, IncidentTopology) const; template VTKM_CONT const typename ConnectivityChooser::ConnectivityArrayType& GetConnectivityArray(VisitTopology, IncidentTopology) const; template VTKM_CONT const typename ConnectivityChooser::OffsetsArrayType& GetOffsetsArray(VisitTopology, IncidentTopology) const; template VTKM_CONT typename ConnectivityChooser::NumIndicesArrayType GetNumIndicesArray(VisitTopology, IncidentTopology) const; template VTKM_CONT bool HasConnectivity(VisitTopology visit, IncidentTopology incident) const { return this->HasConnectivityImpl(visit, incident); } // Can be used to reset a connectivity table, mostly useful for benchmarking. template VTKM_CONT void ResetConnectivity(VisitTopology visit, IncidentTopology incident) { this->ResetConnectivityImpl(visit, incident); } protected: VTKM_CONT void BuildConnectivity(vtkm::cont::DeviceAdapterId, vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) const { VTKM_ASSERT(this->Data->CellPointIds.ElementsValid); // no-op } VTKM_CONT void BuildConnectivity(vtkm::cont::DeviceAdapterId device, vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) const { detail::BuildReverseConnectivity(this->Data->CellPointIds.Connectivity, this->Data->CellPointIds.Offsets, this->Data->NumberOfPoints, this->Data->PointCellIds, device); } VTKM_CONT bool HasConnectivityImpl(vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) const { return this->Data->CellPointIds.ElementsValid; } VTKM_CONT bool HasConnectivityImpl(vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) const { return this->Data->PointCellIds.ElementsValid; } VTKM_CONT void ResetConnectivityImpl(vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) { // Reset entire cell set this->Data->CellPointIds = CellPointIdsType{}; this->Data->PointCellIds = PointCellIdsType{}; this->Data->ConnectivityAdded = -1; this->Data->NumberOfCellsAdded = -1; this->Data->NumberOfPoints = 0; } VTKM_CONT void ResetConnectivityImpl(vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) { this->Data->PointCellIds = PointCellIdsType{}; } // Store internals in a shared pointer so shallow copies stay consistent. // See #2268. struct Internals { CellPointIdsType CellPointIds; PointCellIdsType PointCellIds; // 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; VTKM_CONT Internals() : ConnectivityAdded(-1) , NumberOfCellsAdded(-1) , NumberOfPoints(0) { } }; std::shared_ptr Data; private: VTKM_CONT const CellPointIdsType& GetConnectivity(vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) const { return this->Data->CellPointIds; } VTKM_CONT const CellPointIdsType& GetConnectivity(vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) { return this->Data->CellPointIds; } VTKM_CONT const PointCellIdsType& GetConnectivity(vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) const { return this->Data->PointCellIds; } VTKM_CONT const PointCellIdsType& GetConnectivity(vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell) { return this->Data->PointCellIds; } }; namespace detail { template struct CellSetExplicitConnectivityChooser, vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint> { using ConnectivityType = vtkm::cont::internal::ConnectivityExplicitInternals; }; template struct CellSetExplicitConnectivityChooser { //only specify the shape type as it will be constant as everything //is a vertex. otherwise use the defaults. using ConnectivityType = vtkm::cont::detail::DefaultVisitPointsWithCellsConnectivityExplicit; }; } // namespace detail /// \cond /// Make doxygen ignore this section #ifndef vtk_m_cont_CellSetExplicit_cxx extern template class VTKM_CONT_TEMPLATE_EXPORT CellSetExplicit<>; // default extern template class VTKM_CONT_TEMPLATE_EXPORT CellSetExplicit< typename vtkm::cont::ArrayHandleConstant::StorageTag, VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG, typename vtkm::cont::ArrayHandleCounting::StorageTag>; // CellSetSingleType base #endif /// \endcond } } // namespace vtkm::cont //============================================================================= // Specializations of serialization related classes /// @cond SERIALIZATION namespace vtkm { namespace cont { template struct SerializableTypeString> { static VTKM_CONT const std::string& Get() { static std::string name = "CS_Explicit<" + SerializableTypeString>::Get() + "_ST," + SerializableTypeString>::Get() + "_ST," + SerializableTypeString>::Get() + "_ST>"; return name; } }; } } // vtkm::cont namespace mangled_diy_namespace { template struct Serialization> { private: using Type = vtkm::cont::CellSetExplicit; public: static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs) { vtkmdiy::save(bb, cs.GetNumberOfPoints()); vtkmdiy::save( bb, cs.GetShapesArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{})); vtkmdiy::save( bb, cs.GetConnectivityArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{})); vtkmdiy::save( bb, cs.GetOffsetsArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{})); } static VTKM_CONT void load(BinaryBuffer& bb, Type& cs) { vtkm::Id numberOfPoints = 0; vtkmdiy::load(bb, numberOfPoints); vtkm::cont::ArrayHandle shapes; vtkmdiy::load(bb, shapes); vtkm::cont::ArrayHandle connectivity; vtkmdiy::load(bb, connectivity); vtkm::cont::ArrayHandle offsets; vtkmdiy::load(bb, offsets); cs = Type{}; cs.Fill(numberOfPoints, shapes, connectivity, offsets); } }; } // diy /// @endcond SERIALIZATION #ifndef vtk_m_cont_CellSetExplicit_hxx #include #endif //vtk_m_cont_CellSetExplicit_hxx #endif //vtk_m_cont_CellSetExplicit_h