Commit a234eefe authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Refactoring VTKWriter to support the binary format

Fixes #6
parent 271ca348
Loading
Loading
Loading
Loading

src/TNL/Endianness.h

0 → 100644
+70 −0
Original line number Diff line number Diff line
/***************************************************************************
                          Endianness.h  -  description
                             -------------------
    begin                : Mar 11, 2020
    copyright            : (C) 2020 by Tomas Oberhuber et al.
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

// Implemented by: Jakub Klinkovský

#pragma once

#include <climits>
#include <type_traits>

namespace TNL {

/**
 * \brief Function takes a value and swaps its endianness.
 *
 * Reference: https://stackoverflow.com/a/4956493
 */
template< typename T >
T swapEndianness(T u)
{
   static_assert( CHAR_BIT == 8, "CHAR_BIT != 8" );
   static_assert( std::is_fundamental< T >::value, "swap_endian works only for fundamental types" );

   union
   {
      T u;
      unsigned char u8[sizeof(T)];
   } source, dest;

   source.u = u;

   for (std::size_t k = 0; k < sizeof(T); k++)
      dest.u8[k] = source.u8[sizeof(T) - k - 1];

   return dest.u;
}

/**
 * \brief Function returns `true` iff the system executing the program is little endian.
 */
inline bool
isLittleEndian()
{
   const unsigned int tmp1 = 1;
   const unsigned char *tmp2 = reinterpret_cast<const unsigned char*>(&tmp1);
   if (*tmp2 != 0)
      return true;
   return false;
}

/**
 * \brief Function takes a value and returns its big endian representation.
 */
template< typename T >
T forceBigEndian(T value)
{
   static bool swap = isLittleEndian();
   if( swap )
      return swapEndianness(value);
   return value;
}

}
+33 −5
Original line number Diff line number Diff line
@@ -15,7 +15,8 @@
namespace TNL {
namespace Functions {

template< typename MeshFunction >
template< typename MeshFunction,
          bool = std::is_fundamental< typename MeshFunction::RealType >::value >
class MeshFunctionVTKWriter
{
   using MeshType = typename MeshFunction::MeshType;
@@ -26,11 +27,12 @@ class MeshFunctionVTKWriter
public:
   static bool write( const MeshFunction& function,
                      std::ostream& str,
                      const String& functionName = "cellFunctionValues" )
                      const String& functionName = "cellFunctionValues",
                      Meshes::Writers::VTKFileFormat format = Meshes::Writers::VTKFileFormat::ASCII )
   {
      const MeshType& mesh = function.getMesh();
      MeshWriter::template writeEntities< MeshFunction::getEntitiesDimension() >( mesh, str );
      appendFunction( function, str, functionName );
      MeshWriter::template writeEntities< MeshFunction::getEntitiesDimension() >( mesh, str, format );
      appendFunction( function, str, format, functionName );
      return true;
   }

@@ -39,6 +41,7 @@ public:
   // with different function name.
   static void appendFunction( const MeshFunction& function,
                               std::ostream& str,
                               Meshes::Writers::VTKFileFormat format,
                               const String& functionName )
   {
      const MeshType& mesh = function.getMesh();
@@ -47,8 +50,33 @@ public:
      str << "SCALARS " << functionName << " " << getType< typename MeshFunction::RealType >() << " 1" << std::endl;
      str << "LOOKUP_TABLE default" << std::endl;
      for( GlobalIndex i = 0; i < entitiesCount; i++ ) {
         str << function.getData().getElement( i ) << "\n";
         const typename MeshFunction::RealType value = function.getData().getElement( i );
         using Meshes::Writers::__impl::writeReal;
         writeReal( format, str, value );
         if( format == Meshes::Writers::VTKFileFormat::ASCII )
            str << "\n";
      }
   }
};

template< typename MeshFunction >
class MeshFunctionVTKWriter< MeshFunction, false >
{
public:
   static bool write( const MeshFunction& function,
                      std::ostream& str,
                      const String& functionName = "cellFunctionValues",
                      Meshes::Writers::VTKFileFormat format = Meshes::Writers::VTKFileFormat::ASCII )
   {
      throw std::logic_error( "Unsupported RealType - VTKWriter supports only fundamental types." );
   }

   static void appendFunction( const MeshFunction& function,
                               std::ostream& str,
                               Meshes::Writers::VTKFileFormat format,
                               const String& functionName )
   {
      throw std::logic_error( "Unsupported RealType - VTKWriter supports only fundamental types." );
   }
};

+16 −4
Original line number Diff line number Diff line
@@ -19,8 +19,20 @@ namespace TNL {
namespace Meshes {
namespace Writers {

enum class VTKFileFormat
{
   ASCII,
   BINARY
};

namespace __impl {

// TODO: 64-bit integers are most likely not supported in the BINARY format
inline void writeInt( VTKFileFormat format, std::ostream& str, int value );

template< typename Real >
void writeReal( VTKFileFormat format, std::ostream& str, Real value );

template< typename Mesh, int EntityDimension > struct MeshEntitiesVTKWriter;
template< typename Mesh, int EntityDimension > struct MeshEntityTypesVTKWriter;

@@ -42,15 +54,15 @@ class VTKWriter
public:
   using Index = typename Mesh::GlobalIndexType;

   static void writeAllEntities( const Mesh& mesh, std::ostream& str );
   static void writeAllEntities( const Mesh& mesh, std::ostream& str, VTKFileFormat format = VTKFileFormat::ASCII );

   template< int EntityDimension = Mesh::getMeshDimension() >
   static void writeEntities( const Mesh& mesh, std::ostream& str );
   static void writeEntities( const Mesh& mesh, std::ostream& str, VTKFileFormat format = VTKFileFormat::ASCII );

protected:
   static void writeHeader( const Mesh& mesh, std::ostream& str );
   static void writeHeader( const Mesh& mesh, std::ostream& str, VTKFileFormat format );

   static void writePoints( const Mesh& mesh, std::ostream& str );
   static void writePoints( const Mesh& mesh, std::ostream& str, VTKFileFormat format );
};

} // namespace Writers
+205 −101

File changed.

Preview size limit exceeded, changes collapsed.