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

Added tools for mesh triangulation and planar correction and modified their unit tests

parent ec51a768
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ struct TriangleConfig: public ParentConfig
};

template< EntityDecomposerVersion DecomposerVersion,
          EntityDecomposerVersion SubdecomposerVersion = EntityDecomposerVersion::ConnectEdgesToPoint,
          typename MeshConfig,
          std::enable_if_t< std::is_same< typename MeshConfig::CellTopology, Topologies::Polygon >::value, bool > = true >
auto // returns MeshBuilder
@@ -53,7 +54,7 @@ decomposeMesh( const Mesh< MeshConfig, Devices::Host >& inMesh )
      const auto cell = inMesh.template getEntity< CellDimension >( i );
      indeces[ i ] = EntityDecomposer::getExtraPointsAndEntitiesCount( cell );
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, setCounts );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, setCounts );
   indeces[ inCellsCount ] = { 0, 0 }; // extend exclusive prefix sum by one element to also get result of reduce at the same time
   auto reduction = [] ( const IndexPair& a, const IndexPair& b ) -> IndexPair {
      return { a.first + b.first, a.second + b.second };
@@ -68,7 +69,7 @@ decomposeMesh( const Mesh< MeshConfig, Devices::Host >& inMesh )
   auto copyPoint = [&] ( GlobalIndexType i ) mutable {
      meshBuilder.setPoint( i, inMesh.getPoint( i ) );
   };
   ParallelFor< Devices::Host >::exec( 0, inPointsCount, copyPoint );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inPointsCount, copyPoint );

   // Decompose each cell
   auto decomposeCell = [&] ( GlobalIndexType i ) mutable {
@@ -94,12 +95,13 @@ decomposeMesh( const Mesh< MeshConfig, Devices::Host >& inMesh )

      EntityDecomposer::decompose( cell, addPoint, addCell );
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, decomposeCell );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, decomposeCell );

   return meshBuilder;
}

template< EntityDecomposerVersion DecomposerVersion,
          EntityDecomposerVersion SubdecomposerVersion = EntityDecomposerVersion::ConnectEdgesToPoint,
          typename MeshConfig,
          std::enable_if_t< std::is_same< typename MeshConfig::CellTopology, Topologies::Polygon >::value, bool > = true >
auto // returns Mesh
@@ -154,7 +156,7 @@ decomposeMesh( const Mesh< MeshConfig, Devices::Host >& inMesh )
      const auto cell = inMesh.template getEntity< CellDimension >( i );
      indeces[ i ] = EntityDecomposer::getExtraPointsAndEntitiesCount( cell );
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, setCounts );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, setCounts );
   indeces[ inCellsCount ] = { 0, 0 }; // extend exclusive prefix sum by one element to also get result of reduce at the same time
   auto reduction = [] ( const IndexPair& a, const IndexPair& b ) -> IndexPair {
      return { a.first + b.first, a.second + b.second };
@@ -169,7 +171,7 @@ decomposeMesh( const Mesh< MeshConfig, Devices::Host >& inMesh )
   auto copyPoint = [&] ( GlobalIndexType i ) mutable {
      meshBuilder.setPoint( i, inMesh.getPoint( i ) );
   };
   ParallelFor< Devices::Host >::exec( 0, inPointsCount, copyPoint );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inPointsCount, copyPoint );

   // Decompose each cell
   auto decomposeCell = [&] ( GlobalIndexType i ) mutable {
@@ -196,7 +198,7 @@ decomposeMesh( const Mesh< MeshConfig, Devices::Host >& inMesh )

      EntityDecomposer::decompose( cell, addPoint, addCell );
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, decomposeCell );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, decomposeCell );

   return meshBuilder;
}
+10 −10
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
         indeces[ i ] = EntityDecomposer::getExtraPointsAndEntitiesCount( cell );
      }
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, setCounts );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, setCounts );
   indeces[ inCellsCount ] = { 0, 0 }; // extend exclusive prefix sum by one element to also get result of reduce at the same time
   auto reduction = [] ( const IndexPair& a, const IndexPair& b ) -> IndexPair {
      return { a.first + b.first, a.second + b.second };
@@ -73,7 +73,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
   auto copyPoint = [&] ( GlobalIndexType i ) mutable {
      meshBuilder.setPoint( i, inMesh.getPoint( i ) );
   };
   ParallelFor< Devices::Host >::exec( 0, inPointsCount, copyPoint );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inPointsCount, copyPoint );

   // set corner counts for cells
   NeighborCountsArray cellCornersCounts( outCellsCount );
@@ -93,7 +93,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
         }
      }
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, setCornersCount );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, setCornersCount );
   meshBuilder.setCellCornersCounts( std::move( cellCornersCounts ) );

   // Decompose non-planar cells and copy the rest
@@ -131,7 +131,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
         EntityDecomposer::decompose( cell, addPoint, addCell );
      }
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, decomposeCell );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, decomposeCell );

   return meshBuilder;
}
@@ -179,7 +179,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
         indeces[ i ] = EntityDecomposer::getExtraPointsAndEntitiesCount( face );
      }
   };
   ParallelFor< Devices::Host >::exec( 0, inFacesCount, setCounts );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inFacesCount, setCounts );
   indeces[ inFacesCount ] = { 0, 0 }; // extend exclusive prefix sum by one element to also get result of reduce at the same time
   auto reduction = [] ( const IndexPair& a, const IndexPair& b ) -> IndexPair {
      return { a.first + b.first, a.second + b.second };
@@ -195,7 +195,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
   auto copyPoint = [&] ( GlobalIndexType i ) mutable {
      meshBuilder.setPoint( i, inMesh.getPoint( i ) );
   };
   ParallelFor< Devices::Host >::exec( 0, inPointsCount, copyPoint );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inPointsCount, copyPoint );

   // set corner counts for cells
   NeighborCountsArray cellCornersCounts( outCellsCount );
@@ -212,7 +212,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )

      cellCornersCounts[ i ] = cornersCount;
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, setCellCornersCount );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, setCellCornersCount );
   meshBuilder.setCellCornersCounts( std::move( cellCornersCounts ) );

   // Set corner ids for cells
@@ -228,7 +228,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
         }
      }
   };
   ParallelFor< Devices::Host >::exec( 0, inCellsCount, setCellCornersIds );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inCellsCount, setCellCornersIds );

   // set corner counts for faces
   NeighborCountsArray faceCornersCounts( outFacesCount );
@@ -247,7 +247,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
         }
      }
   };
   ParallelFor< Devices::Host >::exec( 0, inFacesCount, setFaceCornersCount );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inFacesCount, setFaceCornersCount );
   meshBuilder.setFaceCornersCounts( std::move( faceCornersCounts ) );

   // Decompose non-planar faces and copy the rest
@@ -285,7 +285,7 @@ planarCorrection( const Mesh< MeshConfig, Devices::Host >& inMesh )
         EntityDecomposer::decompose( face, addPoint, addFace );
      }
   };
   ParallelFor< Devices::Host >::exec( 0, inFacesCount, decomposeFace );
   ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, inFacesCount, decomposeFace );

   return meshBuilder;
}
+6 −2
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@ ADD_EXECUTABLE(tnl-decompose-grid tnl-decompose-grid.cpp )
ADD_EXECUTABLE(tnl-grid-setup tnl-grid-setup.cpp )
ADD_EXECUTABLE(tnl-grid-to-mesh tnl-grid-to-mesh.cpp )
ADD_EXECUTABLE(tnl-mesh-converter tnl-mesh-converter.cpp )
ADD_EXECUTABLE(tnl-triangulate-mesh tnl-triangulate-mesh.cpp )
ADD_EXECUTABLE(tnl-planar-correct-mesh tnl-planar-correct-mesh.cpp )
ADD_EXECUTABLE(tnl-game-of-life tnl-game-of-life.cpp )
if( BUILD_CUDA )
   CUDA_ADD_EXECUTABLE(tnl-test-distributed-mesh tnl-test-distributed-mesh.cu )
@@ -28,7 +30,7 @@ endif()

find_package( ZLIB )
if( ZLIB_FOUND )
   foreach( target IN ITEMS tnl-init tnl-diff tnl-decompose-grid tnl-grid-to-mesh tnl-mesh-converter tnl-game-of-life tnl-test-distributed-mesh )
   foreach( target IN ITEMS tnl-init tnl-diff tnl-decompose-grid tnl-grid-to-mesh tnl-mesh-converter tnl-triangulate-mesh tnl-planar-correct-mesh tnl-game-of-life tnl-test-distributed-mesh )
      target_compile_definitions(${target} PUBLIC "-DHAVE_ZLIB")
      target_include_directories(${target} PUBLIC ${ZLIB_INCLUDE_DIRS})
      target_link_libraries(${target} ${ZLIB_LIBRARIES})
@@ -37,7 +39,7 @@ endif()

find_package( tinyxml2 QUIET )
if( tinyxml2_FOUND )
   foreach( target IN ITEMS tnl-init tnl-diff tnl-decompose-grid tnl-grid-to-mesh tnl-mesh-converter tnl-game-of-life tnl-test-distributed-mesh )
   foreach( target IN ITEMS tnl-init tnl-diff tnl-decompose-grid tnl-grid-to-mesh tnl-mesh-converter tnl-triangulate-mesh tnl-planar-correct-mesh tnl-game-of-life tnl-test-distributed-mesh )
      target_compile_definitions(${target} PUBLIC "-DHAVE_TINYXML2")
      target_link_libraries(${target} tinyxml2::tinyxml2)
   endforeach()
@@ -72,6 +74,8 @@ INSTALL( TARGETS tnl-init
                 tnl-grid-setup
                 tnl-grid-to-mesh
                 tnl-mesh-converter
                 tnl-triangulate-mesh
                 tnl-planar-correct-mesh
                 tnl-game-of-life
                 tnl-test-distributed-mesh
                 tnl-dicom-reader
+171 −0
Original line number Diff line number Diff line
#include <TNL/Config/parseCommandLine.h>
#include <TNL/Meshes/TypeResolver/resolveMeshType.h>
#include <TNL/Meshes/Writers/VTKWriter.h>
#include <TNL/Meshes/Writers/FPMAWriter.h>
#include <TNL/Meshes/Geometry/getPlanarMesh.h>

using namespace TNL;

struct MeshPlanarCorrectConfigTag {};

namespace TNL {
namespace Meshes {
namespace BuildConfigTags {

/****
 * Turn off all grids.
 */
template<> struct GridRealTag< MeshPlanarCorrectConfigTag, float > { enum { enabled = false }; };
template<> struct GridRealTag< MeshPlanarCorrectConfigTag, double > { enum { enabled = false }; };
template<> struct GridRealTag< MeshPlanarCorrectConfigTag, long double > { enum { enabled = false }; };

/****
 * Unstructured meshes.
 */
template<> struct MeshCellTopologyTag< MeshPlanarCorrectConfigTag, Topologies::Polygon > { enum { enabled = true }; };
template<> struct MeshCellTopologyTag< MeshPlanarCorrectConfigTag, Topologies::Polyhedron > { enum { enabled = true }; };

// Meshes are enabled only for the space dimension equal to 3
template< typename CellTopology, int SpaceDimension >
struct MeshSpaceDimensionTag< MeshPlanarCorrectConfigTag, CellTopology, SpaceDimension >
{ enum { enabled = ( SpaceDimension == 3 ) }; };

// Meshes are enabled only for types explicitly listed below.
template<> struct MeshRealTag< MeshPlanarCorrectConfigTag, float > { enum { enabled = true }; };
template<> struct MeshRealTag< MeshPlanarCorrectConfigTag, double > { enum { enabled = true }; };
template<> struct MeshGlobalIndexTag< MeshPlanarCorrectConfigTag, long int > { enum { enabled = true }; };
template<> struct MeshGlobalIndexTag< MeshPlanarCorrectConfigTag, int > { enum { enabled = true }; };
template<> struct MeshLocalIndexTag< MeshPlanarCorrectConfigTag, short int > { enum { enabled = true }; };

// Config tag specifying the MeshConfig template to use.
template<>
struct MeshConfigTemplateTag< MeshPlanarCorrectConfigTag >
{
   template< typename Cell,
             int SpaceDimension = Cell::dimension,
             typename Real = float,
             typename GlobalIndex = int,
             typename LocalIndex = short int >
   struct MeshConfig
   {
      using CellTopology = Cell;
      using RealType = Real;
      using GlobalIndexType = GlobalIndex;
      using LocalIndexType = LocalIndex;

      static constexpr int spaceDimension = SpaceDimension;
      static constexpr int meshDimension = Cell::dimension;

      static constexpr bool subentityStorage( int entityDimension, int subentityDimension )
      {
         return   (subentityDimension == 0 && entityDimension == meshDimension)
               || (subentityDimension == meshDimension - 1 && entityDimension == meshDimension )
               || (subentityDimension == 0 && entityDimension == meshDimension - 1 );
      }

      static constexpr bool superentityStorage( int entityDimension, int superentityDimension )
      {
         return false;
      }

      static constexpr bool entityTagsStorage( int entityDimension )
      {
         return false;
      }

      static constexpr bool dualGraphStorage()
      {
         return false;
      }
   };
};

} // namespace BuildConfigTags
} // namespace Meshes
} // namespace TNL

using namespace TNL::Meshes;

template< typename Mesh >
auto getPlanarMeshHelper( const Mesh& mesh, const String& decompositionType )
{
   using namespace TNL::Meshes;

   if( decompositionType[0] == 'c' ) {
      return getPlanarMesh< EntityDecomposerVersion::ConnectEdgesToCentroid >( mesh );
   }
   else { // decompositionType[0] == 'p'
      return getPlanarMesh< EntityDecomposerVersion::ConnectEdgesToPoint >( mesh );
   }
}

template< typename Topology >
struct PlanarMeshWriter;

template<>
struct PlanarMeshWriter< Topologies::Polygon >
{
   template< typename Mesh >
   static void exec( const Mesh& mesh, const String& outputFileName )
   {
      using Writer = Meshes::Writers::VTKWriter< Mesh >;
      std::ofstream file( outputFileName );
      Writer writer( file );
      writer.template writeEntities< Mesh::getMeshDimension() >( mesh );
   }
};

template<>
struct PlanarMeshWriter< Topologies::Polyhedron >
{
   template< typename Mesh >
   static void exec( const Mesh& mesh, const String& outputFileName )
   {
      using Writer = Meshes::Writers::FPMAWriter< Mesh >;
      std::ofstream file( outputFileName );
      Writer writer( file );
      writer.writeEntities( mesh );
   }
};

template< typename Mesh >
bool triangulateMesh( const Mesh& mesh, const String& outputFileName, const String& decompositionType )
{
   const auto planarMesh = getPlanarMeshHelper( mesh, decompositionType );
   using PlanarMesh = decltype( planarMesh );
   using CellTopology = typename PlanarMesh::Cell::EntityTopology;
   PlanarMeshWriter< CellTopology >::exec( planarMesh, outputFileName );
   return true;
}

void configSetup( Config::ConfigDescription& config )
{
   config.addDelimiter( "General settings:" );
   config.addRequiredEntry< String >( "input-file", "Input file with the mesh." );
   config.addRequiredEntry< String >( "output-file", "Output mesh file path." );
   config.addRequiredEntry< String >( "decomposition-type", "Type of decomposition to use for non-planar polygons." );
   config.addEntryEnum( "c" );
   config.addEntryEnum( "p" );
}

int main( int argc, char* argv[] )
{
   Config::ParameterContainer parameters;
   Config::ConfigDescription conf_desc;

   configSetup( conf_desc );

   if( ! parseCommandLine( argc, argv, conf_desc, parameters ) )
      return EXIT_FAILURE;

   const String inputFileName = parameters.getParameter< String >( "input-file" );
   const String inputFileFormat = "auto";
   const String outputFileName = parameters.getParameter< String >( "output-file" );
   const String decompositionType = parameters.getParameter< String >( "decomposition-type" );

   auto wrapper = [&] ( auto& reader, auto&& mesh ) -> bool
   {
      return triangulateMesh( mesh, outputFileName, decompositionType );
   };
   return ! Meshes::resolveAndLoadMesh< MeshPlanarCorrectConfigTag, Devices::Host >( wrapper, inputFileName, inputFileFormat );
}
+171 −0
Original line number Diff line number Diff line
#include <TNL/Config/parseCommandLine.h>
#include <TNL/Meshes/TypeResolver/resolveMeshType.h>
#include <TNL/Meshes/Writers/VTKWriter.h>
#include <TNL/Meshes/Writers/VTUWriter.h>
#include <TNL/Meshes/Geometry/getDecomposedMesh.h>

using namespace TNL;

struct MeshTriangulatorConfigTag {};

namespace TNL {
namespace Meshes {
namespace BuildConfigTags {

/****
 * Turn off all grids.
 */
template<> struct GridRealTag< MeshTriangulatorConfigTag, float > { enum { enabled = false }; };
template<> struct GridRealTag< MeshTriangulatorConfigTag, double > { enum { enabled = false }; };
template<> struct GridRealTag< MeshTriangulatorConfigTag, long double > { enum { enabled = false }; };

/****
 * Unstructured meshes.
 */
template<> struct MeshCellTopologyTag< MeshTriangulatorConfigTag, Topologies::Polygon > { enum { enabled = true }; };
template<> struct MeshCellTopologyTag< MeshTriangulatorConfigTag, Topologies::Polyhedron > { enum { enabled = true }; };

// Meshes are enabled only for the space dimension equal to the cell dimension.
template< typename CellTopology, int SpaceDimension >
struct MeshSpaceDimensionTag< MeshTriangulatorConfigTag, CellTopology, SpaceDimension >
{ enum { enabled = ( SpaceDimension == CellTopology::dimension ) }; };

// Meshes are enabled only for types explicitly listed below.
template<> struct MeshRealTag< MeshTriangulatorConfigTag, float > { enum { enabled = true }; };
template<> struct MeshRealTag< MeshTriangulatorConfigTag, double > { enum { enabled = true }; };
template<> struct MeshGlobalIndexTag< MeshTriangulatorConfigTag, long int > { enum { enabled = true }; };
template<> struct MeshGlobalIndexTag< MeshTriangulatorConfigTag, int > { enum { enabled = true }; };
template<> struct MeshLocalIndexTag< MeshTriangulatorConfigTag, short int > { enum { enabled = true }; };

// Config tag specifying the MeshConfig template to use.
template<>
struct MeshConfigTemplateTag< MeshTriangulatorConfigTag >
{
   template< typename Cell,
             int SpaceDimension = Cell::dimension,
             typename Real = float,
             typename GlobalIndex = int,
             typename LocalIndex = short int >
   struct MeshConfig
   {
      using CellTopology = Cell;
      using RealType = Real;
      using GlobalIndexType = GlobalIndex;
      using LocalIndexType = LocalIndex;

      static constexpr int spaceDimension = SpaceDimension;
      static constexpr int meshDimension = Cell::dimension;

      static constexpr bool subentityStorage( int entityDimension, int subentityDimension )
      {
         return   (subentityDimension == 0 && entityDimension == meshDimension)
               || (subentityDimension == meshDimension - 1 && entityDimension == meshDimension )
               || (subentityDimension == 0 && entityDimension == meshDimension - 1 );
      }

      static constexpr bool superentityStorage( int entityDimension, int superentityDimension )
      {
         return false;
      }

      static constexpr bool entityTagsStorage( int entityDimension )
      {
         return false;
      }

      static constexpr bool dualGraphStorage()
      {
         return false;
      }
   };
};

} // namespace BuildConfigTags
} // namespace Meshes
} // namespace TNL

template< typename Mesh >
auto getDecomposedMeshHelper( const Mesh& mesh, const String& decompositionType )
{
   using namespace TNL::Meshes;

   if( decompositionType[0] == 'c' ) {
      if( decompositionType[1] == 'c' ) {
         return getDecomposedMesh< EntityDecomposerVersion::ConnectEdgesToCentroid,
                                   EntityDecomposerVersion::ConnectEdgesToCentroid >( mesh );
      }
      else { // decompositionType[1] == 'p'
         return getDecomposedMesh< EntityDecomposerVersion::ConnectEdgesToCentroid,
                                   EntityDecomposerVersion::ConnectEdgesToPoint >( mesh );
      }
   }
   else { // decompositionType[0] == 'p'
      if( decompositionType[1] == 'c' ) {
         return getDecomposedMesh< EntityDecomposerVersion::ConnectEdgesToPoint,
                                   EntityDecomposerVersion::ConnectEdgesToCentroid >( mesh );
      }
      else { // decompositionType[1] == 'p'
         return getDecomposedMesh< EntityDecomposerVersion::ConnectEdgesToPoint,
                                   EntityDecomposerVersion::ConnectEdgesToPoint >( mesh );
      }
   }
}

template< typename Mesh >
bool triangulateMesh( const Mesh& mesh, const String& outputFileName, const String& outputFormat, const String& decompositionType )
{
   const auto decomposedMesh = getDecomposedMeshHelper( mesh, decompositionType );

   if( outputFormat == "vtk" ) {
      using Writer = Meshes::Writers::VTKWriter< decltype( decomposedMesh ) >;
      std::ofstream file( outputFileName );
      Writer writer( file );
      writer.template writeEntities< Mesh::getMeshDimension() >( decomposedMesh );
   }
   else if( outputFormat == "vtu" ) {
      using Writer = Meshes::Writers::VTUWriter< decltype( decomposedMesh ) >;
      std::ofstream file( outputFileName );
      Writer writer( file );
      writer.template writeEntities< Mesh::getMeshDimension() >( decomposedMesh );
   }

   return true;
}

void configSetup( Config::ConfigDescription& config )
{
   config.addDelimiter( "General settings:" );
   config.addRequiredEntry< String >( "input-file", "Input file with the mesh." );
   config.addRequiredEntry< String >( "output-file", "Output mesh file path." );
   config.addRequiredEntry< String >( "output-file-format", "Output mesh file format." );
   config.addEntryEnum( "vtk" );
   config.addEntryEnum( "vtu" );
   config.addRequiredEntry< String >( "decomposition-type", "Type of decomposition to use." );
   config.addEntryEnum( "cc" );
   config.addEntryEnum( "cp" );
   config.addEntryEnum( "pc" );
   config.addEntryEnum( "pp" );
}

int main( int argc, char* argv[] )
{
   Config::ParameterContainer parameters;
   Config::ConfigDescription conf_desc;

   configSetup( conf_desc );

   if( ! parseCommandLine( argc, argv, conf_desc, parameters ) )
      return EXIT_FAILURE;

   const String inputFileName = parameters.getParameter< String >( "input-file" );
   const String inputFileFormat = "auto";
   const String outputFileName = parameters.getParameter< String >( "output-file" );
   const String outputFileFormat = parameters.getParameter< String >( "output-file-format" );
   const String decompositionType = parameters.getParameter< String >( "decomposition-type" );

   auto wrapper = [&] ( auto& reader, auto&& mesh ) -> bool
   {
      return triangulateMesh( mesh, outputFileName, outputFileFormat, decompositionType );
   };
   return ! Meshes::resolveAndLoadMesh< MeshTriangulatorConfigTag, Devices::Host >( wrapper, inputFileName, inputFileFormat );
}
Loading