Commit b1affc05 authored by Ján Bobot's avatar Ján Bobot Committed by Jakub Klinkovský
Browse files

Extended functionality of Mesh reader and writer

- modified VTKReader and VTUReader to handle reading meshes with mixed cell shapes, that can be generalized to polygons
- modified VTKWriter and VTUWriter to handle writing Polygonal meshes
parent f61ec71a
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
#pragma once

#include <TNL/Meshes/VTKTraits.h>

namespace TNL {
namespace Meshes {
namespace VTK {

template < EntityShape GeneralShape >
struct EntityShapeGroup
{
};

template < EntityShape GeneralShape, int index >
struct EntityShapeGroupElement
{ 
};

template <>
struct EntityShapeGroup< EntityShape::Polygon >
{
   static constexpr int size = 2;
};

template <>
struct EntityShapeGroupElement< EntityShape::Polygon, 0 >
{
   static constexpr EntityShape shape = EntityShape::Triangle;
};

template <>
struct EntityShapeGroupElement< EntityShape::Polygon, 1 >
{
   static constexpr EntityShape shape = EntityShape::Quad;
};

} // namespace VTK
} // namespace Meshes
} // namespace TNL
 No newline at end of file
+49 −0
Original line number Diff line number Diff line
#pragma once

#include <TNL/Meshes/EntityShapeGroup.h>

namespace TNL {
namespace Meshes {
namespace VTK {

template< EntityShape GeneralShape_ >
class EntityShapeGroupChecker
{
public:
   static constexpr EntityShape GeneralShape = GeneralShape_;

   static bool belong( EntityShape shape )
   {
      if( GeneralShape == shape )
      {
         return true;
      }
      else
      {
         bool result = false;
         Algorithms::TemplateStaticFor< int, 0, EntityShapeGroup< GeneralShape >::size, OtherEntitiesChecker >::execHost( result, shape );
         return result;
      }
   }

   static bool bothBelong( EntityShape shape1, EntityShape shape2 )
   {
      return belong( shape1 ) && belong( shape2 );
   }

private:
   template< int index >
   class OtherEntitiesChecker
   {
      public:
         static void exec( bool& result, EntityShape shape )
         {
            EntityShape groupShape = EntityShapeGroupElement< GeneralShape, index >::shape;
            result = result || ( shape == groupShape );
         }
   };
};

} // namespace VTK
} // namespace Meshes
} // namespace TNL
 No newline at end of file
+31 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <TNL/Meshes/Readers/MeshReader.h>
#include <TNL/Endianness.h>
#include <TNL/Meshes/EntityShapeGroupChecker.h>

namespace TNL {
namespace Meshes {
@@ -157,13 +158,33 @@ public:
      }

      // validate cell types
      using PolygonShapeGroupChecker = VTK::EntityShapeGroupChecker< VTK::EntityShape::Polygon >;
      //TODO: uncomment line below later for polyhedrals
      //using PolyhedralShapeGroupChecker = VTK::EntityShapeGroupChecker< VTK::EntityShape::Polyhedral >;
      cellShape = (VTK::EntityShape) cellTypes[0];
      for( auto c : cellTypes )
         if( (VTK::EntityShape) c != cellShape ) {
      {
         if( (VTK::EntityShape) c != entityShape )
         {
            //in case input mesh includes mixed shapes, use more general cellShape ( polygon for 2D, polyhedrals for 3D )
            if( PolygonShapeGroupChecker::bothBelong( cellShape, entityShape ) )
            {
               cellShape = PolygonShapeGroupChecker::GeneralShape;
            }
            //TODO: add group check for polyhedrals later
            /*else if( PolyhedralEntityShapeGroupChecker::bothBelong( cellShape, entityShape ) )
            {
               cellShape = PolyhedralEntityShapeGroupChecker::GeneralShape;
            }*/
            else
            {
               const std::string msg = "Mixed unstructured meshes are not supported. There are cells with type "
                                  + VTK::getShapeName(cellShape) + " and " + VTK::getShapeName((VTK::EntityShape) c);
                                  + VTK::getShapeName(cellShape) + " and " + VTK::getShapeName(entityShape) + ".";
               reset();
               throw MeshReaderError( "VTKReader", msg );
            }
         }
      }

      // find to the CELLS section
      if( ! sectionPositions.count( "CELLS" ) )
@@ -177,7 +198,12 @@ public:
            throw MeshReaderError( "VTKReader", "unable to read enough cells, the file may be invalid or corrupted"
                                                " (entityIndex = " + std::to_string(entityIndex) + ")" );

         if( (VTK::EntityShape) typesArray[ entityIndex ] == cellShape ) {
         VTK::EntityShape entityShape = (VTK::EntityShape) typesArray[ entityIndex ];

         if( entityShape == cellShape ||
             PolygonShapeGroupChecker::bothBelong( cellShape, entityShape ) ) {
            iss.clear();
            iss.str( line );
            // read number of subvertices
            const std::int32_t subvertices = readValue< std::int32_t >( dataFormat, inputFile );
            for( int v = 0; v < subvertices; v++ ) {
+24 −3
Original line number Diff line number Diff line
@@ -94,11 +94,32 @@ class VTUReader
                  return;
               cellShape = (VTK::EntityShape) array[0];
               meshDimension = getEntityDimension( cellShape );
               using PolygonShapeGroupChecker = VTK::EntityShapeGroupChecker< VTK::EntityShape::Polygon >;
               //TODO: uncomment line below later for polyhedrals
               //using PolyhedralShapeGroupChecker = VTK::EntityShapeGroupChecker< VTK::EntityShape::Polyhedral >;

               // TODO: check only entities of the same dimension (edges, faces and cells separately)
               for( auto c : array )
                  if( (VTK::EntityShape) c != cellShape )
               {
                  VTK::EntityShape entityShape = (VTK::EntityShape) c;
                  if( entityShape != cellShape )
                  {
                     if( PolygonShapeGroupChecker::bothBelong( cellShape, entityShape ) )
                     {
                        cellShape = PolygonShapeGroupChecker::GeneralShape;
                     }
                     //TODO: add group check for polyhedrals later
                     /*else if( PolyhedralEntityShapeGroupChecker::bothBelong( cellShape, entityShape ) )
                     {
                        cellShape = PolyhedralEntityShapeGroupChecker::GeneralShape;
                     }*/
                     else
                     {
                        throw MeshReaderError( "VTUReader", "Mixed unstructured meshes are not supported. There are cells with type "
                                                         + VTK::getShapeName(cellShape) + " and " + VTK::getShapeName((VTK::EntityShape) c) + "." );
                                                         + VTK::getShapeName(cellShape) + " and " + VTK::getShapeName(entityShape) + "." );
                     }
                  }
               }
            },
            typesArray
         );
+1 −1
Original line number Diff line number Diff line
@@ -126,10 +126,10 @@ template< typename Topology > struct TopologyToEntityShape {};
template<> struct TopologyToEntityShape< Topologies::Vertex >      { static constexpr EntityShape shape = EntityShape::Vertex; };
template<> struct TopologyToEntityShape< Topologies::Edge >        { static constexpr EntityShape shape = EntityShape::Line; };
template<> struct TopologyToEntityShape< Topologies::Triangle >    { static constexpr EntityShape shape = EntityShape::Triangle; };
template<> struct TopologyToEntityShape< Topologies::Polygon >     { static constexpr EntityShape shape = EntityShape::Polygon; };
template<> struct TopologyToEntityShape< Topologies::Quadrangle >  { static constexpr EntityShape shape = EntityShape::Quad; };
template<> struct TopologyToEntityShape< Topologies::Tetrahedron > { static constexpr EntityShape shape = EntityShape::Tetra; };
template<> struct TopologyToEntityShape< Topologies::Hexahedron >  { static constexpr EntityShape shape = EntityShape::Hexahedron; };
template<> struct TopologyToEntityShape< Topologies::Polygon >     { static constexpr EntityShape shape = EntityShape::Polygon; };

// mapping used in VTKWriter
template< typename GridEntity >
Loading