//============================================================================ // 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_VecAxisAlignedPointCoordinates_h #define vtk_m_VecAxisAlignedPointCoordinates_h #include #include #include #include #include namespace vtkm { namespace detail { /// Specifies the size of VecAxisAlignedPointCoordinates for the given /// dimension. /// template struct VecAxisAlignedPointCoordinatesNumComponents; template <> struct VecAxisAlignedPointCoordinatesNumComponents<1> { static constexpr vtkm::IdComponent NUM_COMPONENTS = 2; }; template <> struct VecAxisAlignedPointCoordinatesNumComponents<2> { static constexpr vtkm::IdComponent NUM_COMPONENTS = 4; }; template <> struct VecAxisAlignedPointCoordinatesNumComponents<3> { static constexpr vtkm::IdComponent NUM_COMPONENTS = 8; }; struct VecAxisAlignedPointCoordinatesOffsetTable { VTKM_EXEC_CONT vtkm::FloatDefault Get(vtkm::Int32 i, vtkm::Int32 j) const { VTKM_STATIC_CONSTEXPR_ARRAY vtkm::FloatDefault offsetTable[8][3] = { { 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f } }; return offsetTable[i][j]; } }; } // namespace detail /// \brief An implicit vector for point coordinates in axis aligned cells. For /// internal use only. /// /// The \c VecAxisAlignedPointCoordinates class is a Vec-like class that holds /// the point coordinates for a axis aligned cell. The class is templated on the /// dimensions of the cell, which can be 1 (for a line). /// /// This is an internal class used to represent coordinates for uniform datasets /// in an execution environment when executing a WorkletMapPointToCell. Users /// should not directly construct this class under any circumstances. Use the /// related ArrayPortalUniformPointCoordinates and /// ArrayHandleUniformPointCoordinates classes instead. /// template class VecAxisAlignedPointCoordinates { public: using ComponentType = vtkm::Vec3f; static constexpr vtkm::IdComponent NUM_COMPONENTS = detail::VecAxisAlignedPointCoordinatesNumComponents::NUM_COMPONENTS; VTKM_EXEC_CONT VecAxisAlignedPointCoordinates(ComponentType origin = ComponentType(0, 0, 0), ComponentType spacing = ComponentType(1, 1, 1)) : Origin(origin) , Spacing(spacing) { } VTKM_EXEC_CONT vtkm::IdComponent GetNumberOfComponents() const { return NUM_COMPONENTS; } template VTKM_EXEC_CONT void CopyInto(vtkm::Vec& dest) const { vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->GetNumberOfComponents()); for (vtkm::IdComponent index = 0; index < numComponents; index++) { dest[index] = (*this)[index]; } } VTKM_EXEC_CONT ComponentType operator[](vtkm::IdComponent index) const { detail::VecAxisAlignedPointCoordinatesOffsetTable table; return ComponentType(this->Origin[0] + table.Get(index, 0) * this->Spacing[0], this->Origin[1] + table.Get(index, 1) * this->Spacing[1], this->Origin[2] + table.Get(index, 2) * this->Spacing[2]); } VTKM_EXEC_CONT const ComponentType& GetOrigin() const { return this->Origin; } VTKM_EXEC_CONT const ComponentType& GetSpacing() const { return this->Spacing; } private: // Position of lower left point. ComponentType Origin; // Spacing in the x, y, and z directions. ComponentType Spacing; }; template struct TypeTraits> { using NumericTag = vtkm::TypeTraitsRealTag; using DimensionalityTag = TypeTraitsVectorTag; VTKM_EXEC_CONT static vtkm::VecAxisAlignedPointCoordinates ZeroInitialization() { return vtkm::VecAxisAlignedPointCoordinates(vtkm::Vec3f(0, 0, 0), vtkm::Vec3f(0, 0, 0)); } }; template struct VecTraits> { using VecType = vtkm::VecAxisAlignedPointCoordinates; using ComponentType = vtkm::Vec3f; using BaseComponentType = vtkm::FloatDefault; using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents; using IsSizeStatic = vtkm::VecTraitsTagSizeStatic; static constexpr vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS; VTKM_EXEC_CONT static vtkm::IdComponent GetNumberOfComponents(const VecType&) { return NUM_COMPONENTS; } VTKM_EXEC_CONT static ComponentType GetComponent(const VecType& vector, vtkm::IdComponent componentIndex) { return vector[componentIndex]; } // These are a bit of a hack since VecAxisAlignedPointCoordinates only supports one component // type. Using these might not work as expected. template using ReplaceComponentType = vtkm::Vec; template using ReplaceBaseComponentType = vtkm::Vec, NUM_COMPONENTS>; template VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec& dest) { src.CopyInto(dest); } }; /// Helper function for printing out vectors during testing. /// template inline VTKM_CONT std::ostream& operator<<( std::ostream& stream, const vtkm::VecAxisAlignedPointCoordinates& vec) { stream << "["; for (vtkm::IdComponent component = 0; component < vec.NUM_COMPONENTS - 1; component++) { stream << vec[component] << ","; } return stream << vec[vec.NUM_COMPONENTS - 1] << "]"; } } // namespace vtkm #endif //vtk_m_VecAxisAlignedPointCoordinates_h