//============================================================================ // 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 2014 Sandia Corporation. // Copyright 2014 UT-Battelle, LLC. // Copyright 2014 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #ifndef vtk_m_CellShape_h #define vtk_m_CellShape_h #include #include VTKM_THIRDPARTY_PRE_INCLUDE #include VTKM_THIRDPARTY_POST_INCLUDE namespace vtkm { /// CellShapeId identifies the type of each cell. Currently these are designed /// to match up with VTK cell types. /// enum CellShapeIdEnum { // Linear cells CELL_SHAPE_EMPTY = 0, CELL_SHAPE_VERTEX = 1, //CELL_SHAPE_POLY_VERTEX = 2, CELL_SHAPE_LINE = 3, //CELL_SHAPE_POLY_LINE = 4, CELL_SHAPE_TRIANGLE = 5, //CELL_SHAPE_TRIANGLE_STRIP = 6, CELL_SHAPE_POLYGON = 7, //CELL_SHAPE_PIXEL = 8, CELL_SHAPE_QUAD = 9, CELL_SHAPE_TETRA = 10, //CELL_SHAPE_VOXEL = 11, CELL_SHAPE_HEXAHEDRON = 12, CELL_SHAPE_WEDGE = 13, CELL_SHAPE_PYRAMID = 14, NUMBER_OF_CELL_SHAPES }; // If you wish to add cell shapes to this list, in addition to adding an index // to the enum above, you at a minimum need to define an associated tag with // VTKM_DEFINE_CELL_TAG and add a condition to the vtkmGenericCellShapeMacro. // There are also many other cell-specific features that code might expect such // as \c CellTraits and interpolations. namespace internal { /// A class that can be used to determine if a class is a CellShapeTag or not. /// The class will be either boost::true_type or boost::false_type. /// template struct CellShapeTagCheck : boost::false_type { }; } // namespace internal /// Checks that the argument is a proper cell shape tag. This is a handy /// concept check to make sure that a template argument is a proper cell shape /// tag. /// #define VTKM_IS_CELL_SHAPE_TAG(tag) \ VTKM_STATIC_ASSERT_MSG( \ ::vtkm::internal::CellShapeTagCheck::value, \ "Provided type is not a valid VTK-m cell shape tag.") /// A traits-like class to get an CellShapeId known at compile time to a tag. /// template struct CellShapeIdToTag { // If you get a compile error for this class about Id not being defined, that // probably means you are using an ID that does not have a defined cell // shape. typedef boost::false_type valid; }; // Define a tag for each cell shape as well as the support structs to go // between tags and ids. The following macro is only valid here. #define VTKM_DEFINE_CELL_TAG(name, idname) \ struct CellShapeTag ## name { \ static const vtkm::IdComponent Id = vtkm::idname; \ }; \ namespace internal { \ template<> \ struct CellShapeTagCheck : boost::true_type { }; \ } \ VTKM_EXEC_CONT_EXPORT \ const char *GetCellShapeName(vtkm::CellShapeTag ## name) { \ return #name; \ } \ template<> \ struct CellShapeIdToTag { \ typedef boost::true_type valid; \ typedef vtkm::CellShapeTag ## name Tag; \ } VTKM_DEFINE_CELL_TAG(Empty, CELL_SHAPE_EMPTY); VTKM_DEFINE_CELL_TAG(Vertex, CELL_SHAPE_VERTEX); //VTKM_DEFINE_CELL_TAG(PolyVertex, CELL_SHAPE_POLY_VERTEX); VTKM_DEFINE_CELL_TAG(Line, CELL_SHAPE_LINE); //VTKM_DEFINE_CELL_TAG(PolyLine, CELL_SHAPE_POLY_LINE); VTKM_DEFINE_CELL_TAG(Triangle, CELL_SHAPE_TRIANGLE); //VTKM_DEFINE_CELL_TAG(TriangleStrip, CELL_SHAPE_TRIANGLE_STRIP); VTKM_DEFINE_CELL_TAG(Polygon, CELL_SHAPE_POLYGON); //VTKM_DEFINE_CELL_TAG(Pixel, CELL_SHAPE_PIXEL); VTKM_DEFINE_CELL_TAG(Quad, CELL_SHAPE_QUAD); VTKM_DEFINE_CELL_TAG(Tetra, CELL_SHAPE_TETRA); //VTKM_DEFINE_CELL_TAG(Voxel, CELL_SHAPE_VOXEL); VTKM_DEFINE_CELL_TAG(Hexahedron, CELL_SHAPE_HEXAHEDRON); VTKM_DEFINE_CELL_TAG(Wedge, CELL_SHAPE_WEDGE); VTKM_DEFINE_CELL_TAG(Pyramid, CELL_SHAPE_PYRAMID); #undef VTKM_DEFINE_CELL_TAG /// A special cell shape tag that holds a cell shape that is not known at /// compile time. Unlike other cell set tags, the Id field is set at runtime /// so its value cannot be used in template parameters. You need to use /// \c vtkmGenericCellShapeMacro to specialize on the cell type. /// struct CellShapeTagGeneric { VTKM_EXEC_CONT_EXPORT CellShapeTagGeneric(vtkm::IdComponent shape) : Id(shape) { } vtkm::IdComponent Id; }; #define vtkmGenericCellShapeMacroCase(cellShapeId, call) \ case vtkm::cellShapeId: \ { \ typedef \ vtkm::CellShapeIdToTag::Tag CellShapeTag; \ call; \ } \ break /// \brief A macro used in a \c switch statement to determine cell shape. /// /// The \c vtkmGenericCellShapeMacro is a series of case statements for all /// of the cell shapes supported by VTK-m. This macro is intended to be used /// inside of a switch statement on a cell type. For each cell shape condition, /// a \c CellShapeTag typedef is created and the given \c call is executed. /// /// A typical use case of this class is to create the specialization of a /// function overloaded on a cell shape tag for the generic cell shape like as /// following. /// /// \code{.cpp} /// template /// VTKM_EXEC_EXPORT /// void MyCellOperation(vtkm::CellShapeTagGeneric cellShape, /// const vtkm::exec::FunctorBase &worklet) /// { /// switch(cellShape.CellShapeId) /// { /// vtkmGenericCellShapeMacro( /// MyCellOperation(CellShapeTag()) /// ); /// default: worklet.RaiseError("Encountered unknown cell shape."); break /// } /// } /// \endcode /// /// Note that \c vtkmGenericCellShapeMacro does not have a default case. You /// should consider adding one that gives a /// #define vtkmGenericCellShapeMacro(call) \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_EMPTY, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_VERTEX, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_LINE, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_TRIANGLE, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_POLYGON, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_QUAD, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_TETRA, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_HEXAHEDRON, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_WEDGE, call); \ vtkmGenericCellShapeMacroCase(CELL_SHAPE_PYRAMID, call) } // namespace vtkm #endif //vtk_m_CellShape_h