From 8585bc52c0212d5f8b0d45c12697ad3fe640321c Mon Sep 17 00:00:00 2001
From: Jan Bobot <bobotjan@fit.cvut.cz>
Date: Fri, 3 Sep 2021 19:37:06 +0200
Subject: [PATCH] Refactored MeshBuilder to store face seed indeces in a matrix
 instead of array of EntitySeeds

---
 src/TNL/Meshes/Geometry/EntityDecomposer.h    |  20 +-
 src/TNL/Meshes/Geometry/getPlanarMesh.h       |  35 +-
 src/TNL/Meshes/Mesh.h                         |   2 +-
 src/TNL/Meshes/Mesh.hpp                       |   2 +-
 src/TNL/Meshes/MeshBuilder.h                  |  60 ++--
 .../initializer/EntityInitializer.h           |  18 +-
 .../initializer/EntitySeedMatrix.h            | 318 ++++++++++++++++++
 .../MeshDetails/initializer/Initializer.h     |  44 +--
 .../MeshDetails/traits/MeshEntityTraits.h     |   4 +-
 .../Meshes/MeshDetails/traits/MeshTraits.h    |   4 +
 src/TNL/Meshes/Readers/MeshReader.h           |  12 +-
 src/UnitTests/Meshes/MeshGeometryTest.h       |  85 ++---
 src/UnitTests/Meshes/MeshTest.h               |  44 +--
 13 files changed, 506 insertions(+), 142 deletions(-)
 create mode 100644 src/TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h

diff --git a/src/TNL/Meshes/Geometry/EntityDecomposer.h b/src/TNL/Meshes/Geometry/EntityDecomposer.h
index ea4ae3b29a..89e995d8f4 100644
--- a/src/TNL/Meshes/Geometry/EntityDecomposer.h
+++ b/src/TNL/Meshes/Geometry/EntityDecomposer.h
@@ -27,8 +27,8 @@ struct EntityDecomposer;
 template< typename MeshConfig, EntityDecomposerVersion SubentityDecomposerVersion > // SubentityDecomposerVersion is not used for polygons
 struct EntityDecomposer< MeshConfig, Topologies::Polygon, EntityDecomposerVersion::ConnectEdgesToCentroid, SubentityDecomposerVersion >
 {
-   using Device = typename Devices::Host;
-   using Topology = typename Topologies::Polygon;
+   using Device = Devices::Host;
+   using Topology = Topologies::Polygon;
    using MeshEntityType = MeshEntity< MeshConfig, Device, Topology >;
    using VertexMeshEntityType = typename MeshEntityType::template SubentityTraits< 0 >::SubentityType;
    using PointType = typename VertexMeshEntityType::PointType;
@@ -76,8 +76,8 @@ struct EntityDecomposer< MeshConfig, Topologies::Polygon, EntityDecomposerVersio
 template< typename MeshConfig, EntityDecomposerVersion SubentityDecomposerVersion > // SubentityDecomposerVersion is not used for polygons
 struct EntityDecomposer< MeshConfig, Topologies::Polygon, EntityDecomposerVersion::ConnectEdgesToPoint, SubentityDecomposerVersion >
 {
-   using Device = typename Devices::Host;
-   using Topology = typename Topologies::Polygon;
+   using Device = Devices::Host;
+   using Topology = Topologies::Polygon;
    using MeshEntityType = MeshEntity< MeshConfig, Device, Topology >;
    using VertexMeshEntityType = typename MeshEntityType::template SubentityTraits< 0 >::SubentityType;
    using PointType = typename VertexMeshEntityType::PointType;
@@ -111,9 +111,9 @@ struct EntityDecomposer< MeshConfig, Topologies::Polygon, EntityDecomposerVersio
 template< typename MeshConfig, EntityDecomposerVersion SubentityDecomposerVersion >
 struct EntityDecomposer< MeshConfig, Topologies::Polyhedron, EntityDecomposerVersion::ConnectEdgesToCentroid, SubentityDecomposerVersion >
 {
-   using Device = typename Devices::Host;
-   using CellTopology = typename Topologies::Polyhedron;
-   using FaceTopology = typename Topologies::Polygon;
+   using Device = Devices::Host;
+   using CellTopology = Topologies::Polyhedron;
+   using FaceTopology = Topologies::Polygon;
    using MeshEntityType = MeshEntity< MeshConfig, Device, CellTopology >;
    using VertexMeshEntityType = typename MeshEntityType::template SubentityTraits< 0 >::SubentityType;
    using PointType = typename VertexMeshEntityType::PointType;
@@ -164,9 +164,9 @@ template< typename MeshConfig, EntityDecomposerVersion SubentityDecomposerVersio
 struct EntityDecomposer< MeshConfig, Topologies::Polyhedron, EntityDecomposerVersion::ConnectEdgesToPoint, SubentityDecomposerVersion >
 {
    // https://mathoverflow.net/a/7672
-   using Device = typename Devices::Host;
-   using CellTopology = typename Topologies::Polyhedron;
-   using FaceTopology = typename Topologies::Polygon;
+   using Device = Devices::Host;
+   using CellTopology = Topologies::Polyhedron;
+   using FaceTopology = Topologies::Polygon;
    using MeshEntityType = MeshEntity< MeshConfig, Device, CellTopology >;
    using MeshSubentityType = MeshEntity< MeshConfig, Device, FaceTopology >;
    using VertexMeshEntityType = typename MeshEntityType::template SubentityTraits< 0 >::SubentityType;
diff --git a/src/TNL/Meshes/Geometry/getPlanarMesh.h b/src/TNL/Meshes/Geometry/getPlanarMesh.h
index 99f9c268dd..e271183743 100644
--- a/src/TNL/Meshes/Geometry/getPlanarMesh.h
+++ b/src/TNL/Meshes/Geometry/getPlanarMesh.h
@@ -180,6 +180,24 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
       }
    }
 
+   // set corners count for face seeds
+   GlobalIndexType setFacesCount = 0;
+   for( GlobalIndexType i = 0; i < inFacesCount; i++ ) {
+      const auto & faceMapping = faceMap[ i ];
+      const bool isPlanarRes = ( faceMapping.second - faceMapping.first ) == 1;
+      if( isPlanarRes ) {
+         const auto face = inMesh.template getEntity< 2 >( i );
+         const auto verticesCount = face.template getSubentitiesCount< 0 >();
+         meshBuilder.setFaceCornersCount( setFacesCount++, verticesCount );
+      }
+      else {
+         for( GlobalIndexType j = faceMapping.first; j < faceMapping.second; j++ ) {
+            meshBuilder.setFaceCornersCount( setFacesCount++, 3 );
+         }
+      }
+   }
+   meshBuilder.initializeFaceSeeds();
+
    // Lambda for creating new points
    auto createPointFunc = [&] ( const PointType & point ) {
       const auto pointIdx = setPointsCount++;
@@ -188,13 +206,13 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
    };
 
    // Lambda for setting seed of decomposed triangle
-   GlobalIndexType setFacesCount = 0;
+   setFacesCount = 0;
    auto setDecomposedFaceFunc = [&] ( GlobalIndexType v0, GlobalIndexType v1, GlobalIndexType v2 ) {
-      auto & entitySeed = meshBuilder.getFaceSeed( setFacesCount++ );
-      entitySeed.setCornersCount( 3 );
-      entitySeed.setCornerId( 0, v0 );
-      entitySeed.setCornerId( 1, v1 );
-      entitySeed.setCornerId( 2, v2 );
+      const GlobalIndexType faceId = setFacesCount++;
+      auto seed = meshBuilder.getFaceSeed( faceId );
+      seed.setCornerId( 0, v0 );
+      seed.setCornerId( 1, v1 );
+      seed.setCornerId( 2, v2 );
    };
 
    // Decompose non-planar faces and copy the rest
@@ -204,10 +222,9 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
       const auto & faceMapping = faceMap[ i ];
       const bool isPlanarRes = ( faceMapping.second - faceMapping.first ) == 1; // Face was planar if face maps only onto 1 face
       if( isPlanarRes ) { // Copy planar faces
-         auto & faceSeed = meshBuilder.getFaceSeed( setFacesCount++ );
-         faceSeed.setCornersCount( verticesCount );
+         const GlobalIndexType faceId = setFacesCount++;
          for( LocalIndexType j = 0; j < verticesCount; j++ ) {
-            faceSeed.setCornerId( j, face.template getSubentityIndex< 0 >( j ) );
+            meshBuilder.getFaceSeed( faceId ).setCornerId( j, face.template getSubentityIndex< 0 >( j ) );
          }
       }
       else { // Decompose non-planar cells
diff --git a/src/TNL/Meshes/Mesh.h b/src/TNL/Meshes/Mesh.h
index c885cf5125..8b04acbd4f 100644
--- a/src/TNL/Meshes/Mesh.h
+++ b/src/TNL/Meshes/Mesh.h
@@ -50,7 +50,7 @@ class MeshInitializableBase
 
       // The points and cellSeeds arrays will be reset when not needed to save memory.
       void init( typename MeshTraitsType::PointArrayType& points,
-                 typename MeshTraitsType::FaceSeedArrayType& faceSeeds,
+                 typename MeshTraitsType::FaceSeedMatrixType& faceSeeds,
                  typename MeshTraitsType::CellSeedArrayType& cellSeeds );
 };
 
diff --git a/src/TNL/Meshes/Mesh.hpp b/src/TNL/Meshes/Mesh.hpp
index 5e2b72193c..d23a335775 100644
--- a/src/TNL/Meshes/Mesh.hpp
+++ b/src/TNL/Meshes/Mesh.hpp
@@ -27,7 +27,7 @@ template< typename MeshConfig, typename Device, typename MeshType >
 void
 MeshInitializableBase< MeshConfig, Device, MeshType >::
 init( typename MeshTraitsType::PointArrayType& points,
-      typename MeshTraitsType::FaceSeedArrayType& faceSeeds,
+      typename MeshTraitsType::FaceSeedMatrixType& faceSeeds,
       typename MeshTraitsType::CellSeedArrayType& cellSeeds )
 {
    MeshType* mesh = static_cast< MeshType* >( this );
diff --git a/src/TNL/Meshes/MeshBuilder.h b/src/TNL/Meshes/MeshBuilder.h
index cb6fa23b68..6269169759 100644
--- a/src/TNL/Meshes/MeshBuilder.h
+++ b/src/TNL/Meshes/MeshBuilder.h
@@ -25,15 +25,17 @@ template< typename Mesh >
 class MeshBuilder
 {
 public:
-   using MeshType        = Mesh;
-   using MeshTraitsType  = typename MeshType::MeshTraitsType;
-   using GlobalIndexType = typename MeshTraitsType::GlobalIndexType;
-   using LocalIndexType  = typename MeshTraitsType::LocalIndexType;
-   using PointType       = typename MeshTraitsType::PointType;
-   using CellTopology    = typename MeshTraitsType::CellTopology;
-   using CellSeedType    = typename MeshTraitsType::CellSeedType;
-   using FaceSeedType    = typename MeshTraitsType::FaceSeedType;
-
+   using MeshType           = Mesh;
+   using MeshTraitsType     = typename MeshType::MeshTraitsType;
+   using GlobalIndexType    = typename MeshTraitsType::GlobalIndexType;
+   using LocalIndexType     = typename MeshTraitsType::LocalIndexType;
+   using PointType          = typename MeshTraitsType::PointType;
+   using CellTopology       = typename MeshTraitsType::CellTopology;
+   using CellSeedType       = typename MeshTraitsType::CellSeedType;
+   using CellSeedMatrixType = typename MeshTraitsType::CellSeedMatrixType;
+   using FaceSeedMatrixType = typename MeshTraitsType::FaceSeedMatrixType;
+   using FaceSeedType       = typename FaceSeedMatrixType::EntitySeedMatrixSeed;
+   
    void setPointsCount( const GlobalIndexType& points )
    {
       this->points.setSize( points );
@@ -43,7 +45,17 @@ public:
 
    void setFacesCount( const GlobalIndexType& facesCount )
    {
-      this->faceSeeds.setSize( facesCount );
+      this->faceSeeds.setDimensions( facesCount, this->points.getSize() );
+   }
+
+   void setFaceCornersCount( const GlobalIndexType& faceIndex, const LocalIndexType& cornersCount )
+   {
+      this->faceSeeds.setEntityCornersCount( faceIndex, cornersCount );
+   }
+
+   void initializeFaceSeeds()
+   {
+      this->faceSeeds.initializeRows();
    }
 
    void setCellsCount( const GlobalIndexType& cellsCount )
@@ -58,7 +70,7 @@ public:
 
    GlobalIndexType getFacesCount() const
    {
-      return this->faceSeeds.getSize();
+      return this->faceSeeds.getEntitiesCount();
    }
 
    GlobalIndexType getCellsCount() const
@@ -73,9 +85,9 @@ public:
       this->pointsSet[ index ] = true;
    }
 
-   FaceSeedType& getFaceSeed( GlobalIndexType index )
+   FaceSeedType getFaceSeed( GlobalIndexType index )
    {
-      return this->faceSeeds[ index ];
+      return this->faceSeeds.getSeed( index );
    }
 
    CellSeedType& getCellSeed( GlobalIndexType index )
@@ -92,10 +104,10 @@ public:
    }
 
 private:
-   using PointArrayType    = typename MeshTraitsType::PointArrayType;
-   using CellSeedArrayType = typename MeshTraitsType::CellSeedArrayType;
-   using FaceSeedArrayType = typename MeshTraitsType::FaceSeedArrayType;
-   using BoolVector        = Containers::Vector< bool, Devices::Host, GlobalIndexType >;
+   using PointArrayType     = typename MeshTraitsType::PointArrayType;
+   using CellSeedArrayType  = typename MeshTraitsType::CellSeedArrayType;
+   using FaceSeedArrayType  = typename MeshTraitsType::FaceSeedArrayType;
+   using BoolVector         = Containers::Vector< bool, Devices::Host, GlobalIndexType >;
 
    bool validate() const
    {
@@ -129,13 +141,13 @@ private:
       else
       {
          for( GlobalIndexType i = 0; i < getFacesCount(); i++ ) {
-            const auto& cornerIds = this->faceSeeds[ i ].getCornerIds();
-            for( LocalIndexType j = 0; j < cornerIds.getSize(); j++ ) {
-               if( cornerIds[ j ] < 0 || getPointsCount() <= cornerIds[ j ] ) {
-                  std::cerr << "face seed " << i << " is referencing unavailable point " << cornerIds[ j ] << std::endl;
+            const auto faceSeed = this->faceSeeds.getSeed( i );
+            for( LocalIndexType j = 0; j < faceSeed.getCornersCount(); j++ ) {
+               if( faceSeed.getCornerId( j ) < 0 || getPointsCount() <= faceSeed.getCornerId( j ) ) {
+                  std::cerr << "face seed " << i << " is referencing unavailable point " << faceSeed.getCornerId( j ) << std::endl;
                   return false;
                }
-               assignedPoints[ cornerIds[ j ] ] = true;
+               assignedPoints[ faceSeed.getCornerId( j ) ] = true;
             }
          }
 
@@ -145,7 +157,7 @@ private:
          }
 
          BoolVector assignedFaces;
-         assignedFaces.setLike( faceSeeds );
+         assignedFaces.setSize( faceSeeds.getEntitiesCount() );
          assignedFaces.setValue( false );
 
          for( GlobalIndexType i = 0; i < getCellsCount(); i++ ) {
@@ -169,7 +181,7 @@ private:
    }
 
    PointArrayType points;
-   FaceSeedArrayType faceSeeds;
+   FaceSeedMatrixType faceSeeds;
    CellSeedArrayType cellSeeds;
    BoolVector pointsSet;
 };
diff --git a/src/TNL/Meshes/MeshDetails/initializer/EntityInitializer.h b/src/TNL/Meshes/MeshDetails/initializer/EntityInitializer.h
index 936476ed65..358c1a18b9 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/EntityInitializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/EntityInitializer.h
@@ -49,13 +49,14 @@ class EntityInitializer
                                             DimensionTag< EntityTopology::dimension >,
                                             DimensionTag< MeshTraits< MeshConfig >::meshDimension > >;
 
-   using MeshTraitsType   = MeshTraits< MeshConfig >;
-   using GlobalIndexType  = typename MeshTraitsType::GlobalIndexType;
-   using LocalIndexType   = typename MeshTraitsType::LocalIndexType;
+   using MeshTraitsType      = MeshTraits< MeshConfig >;
+   using GlobalIndexType     = typename MeshTraitsType::GlobalIndexType;
+   using LocalIndexType      = typename MeshTraitsType::LocalIndexType;
 
-   using SeedType         = EntitySeed< MeshConfig, EntityTopology >;
-   using InitializerType  = Initializer< MeshConfig >;
+   using SeedType            = EntitySeed< MeshConfig, EntityTopology >;
+   using InitializerType     = Initializer< MeshConfig >;
    using NeighborCountsArray = typename MeshTraitsType::NeighborCountsArray;
+   using SeedMatrixType      = EntitySeedMatrix< MeshConfig, EntityTopology >;
 
 public:
    static void initSubvertexMatrix( NeighborCountsArray& capacities, InitializerType& initializer )
@@ -69,6 +70,13 @@ public:
       for( LocalIndexType i = 0; i < entitySeed.getCornerIds().getSize(); i++ )
          initializer.template setSubentityIndex< EntityTopology::dimension, 0 >( entityIndex, i, entitySeed.getCornerIds()[ i ] );
    }
+
+   static void initSubvertexMatrix( SeedMatrixType& seeds, InitializerType& initializer )
+   {
+      auto& subvertexMatrix = initializer.template getSubentitiesMatrix< EntityTopology::dimension, 0 >();
+      subvertexMatrix = std::move( seeds.getMatrix() );
+      initializer.template initSubentitiesCounts< EntityTopology::dimension, 0 >( seeds.getEntityCornerCounts() );
+   }
 };
 
 template< typename MeshConfig,
diff --git a/src/TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h b/src/TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h
new file mode 100644
index 0000000000..3e9781d2b3
--- /dev/null
+++ b/src/TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h
@@ -0,0 +1,318 @@
+#pragma once
+
+//#include <TNL/Meshes/MeshDetails/traits/MeshTraits.h>
+#include <TNL/Meshes/Topologies/IsDynamicTopology.h>
+
+namespace TNL {
+namespace Meshes {
+
+template< typename MeshConfig,
+          typename Device>
+class MeshTraits;
+
+template< typename MeshConfig,
+          typename EntityTopology,
+          bool IsDynamicTopology = Topologies::IsDynamicTopology< EntityTopology >::value >
+class EntitySeedMatrix;
+
+template< typename MeshConfig,
+          typename EntityTopology >
+class EntitySeedMatrix< MeshConfig, EntityTopology, false >
+{
+   using MeshTraitsType = MeshTraits< MeshConfig, Devices::Host >;
+
+   public:
+      using GlobalIndexType = typename MeshTraitsType::GlobalIndexType;
+      using LocalIndexType  = typename MeshTraitsType::LocalIndexType;
+      using SubentityTraitsType = typename MeshTraitsType::template SubentityTraits< EntityTopology, 0 >;
+      using SubentityMatrixType = typename MeshTraitsType::template SubentityMatrixType< EntityTopology::dimension >;
+      using NeighborCountsArray = typename MeshTraitsType::NeighborCountsArray;
+
+      static constexpr int cornersCount = SubentityTraitsType::count;
+
+      class EntitySeedMatrixSeed
+      {
+         using RowView = typename SubentityMatrixType::RowView;
+
+         public:
+            EntitySeedMatrixSeed( const RowView& matrixRow )
+            : row( matrixRow )
+            {}
+
+            static constexpr LocalIndexType getCornersCount()
+            {
+               return cornersCount;
+            }
+
+            void setCornerId( const LocalIndexType& cornerIndex, const GlobalIndexType& pointIndex )
+            {
+               TNL_ASSERT_GE( cornerIndex, 0, "corner index must be non-negative" );
+               TNL_ASSERT_LT( cornerIndex, getCornersCount(), "corner index is out of bounds" );
+               TNL_ASSERT_GE( pointIndex, 0, "point index must be non-negative" );
+               this->row.setColumnIndex( cornerIndex, pointIndex );
+            }
+
+            GlobalIndexType getCornerId( const LocalIndexType& cornerIndex ) const
+            {
+               return this->row.getColumnIndex( cornerIndex );
+            }
+
+         private:
+            RowView row;
+      };
+
+      class ConstEntitySeedMatrixSeed
+      {
+         using ConstRowView = typename SubentityMatrixType::ConstRowView;
+
+         public:
+            ConstEntitySeedMatrixSeed( const ConstRowView& matrixRow )
+            : row( matrixRow )
+            {}
+
+            static constexpr LocalIndexType getCornersCount()
+            {
+               return cornersCount;
+            }
+
+            GlobalIndexType getCornerId( const LocalIndexType& cornerIndex ) const
+            {
+               return this->row.getColumnIndex( cornerIndex );
+            }
+
+         private:
+            ConstRowView row;
+      };
+
+      void setDimensions( const GlobalIndexType& entitiesCount, const GlobalIndexType& pointsCount )
+      {
+         matrix.setDimensions( entitiesCount, pointsCount );
+
+         NeighborCountsArray capacities( entitiesCount );
+         capacities.setValue( cornersCount );
+         matrix.setRowCapacities( capacities );
+      }
+
+      // This method is only here for compatibility with specialization for dynamic entity topologies
+      void setEntityCornersCount( const GlobalIndexType& entityIndex, const LocalIndexType& count )
+      {}
+
+      // This method is only here for compatibility with specialization for dynamic entity topologies
+      void initializeRows()
+      {}
+
+      void reset()
+      {
+         matrix.reset();
+      }
+
+      void setSeedIndex( const GlobalIndexType& entityIndex, const LocalIndexType& localIndex, const GlobalIndexType& globalIndex )
+      {
+         matrix.getRow( entityIndex ).setElement( localIndex, globalIndex, true );
+      }
+
+      GlobalIndexType getEntitiesCount() const
+      {
+         return matrix.getRows();
+      }
+
+      constexpr LocalIndexType getEntityCornersCount( const GlobalIndexType& entityIndex ) const
+      {
+         return cornersCount;
+      }
+
+      GlobalIndexType getSeedIndex( const GlobalIndexType& entityIndex, const LocalIndexType& localIndex ) const
+      {
+         return matrix.getRow( entityIndex ).getColumnIndex( localIndex );
+      }
+
+      SubentityMatrixType& getMatrix()
+      {
+         return matrix;
+      }
+
+      const SubentityMatrixType& getMatrix() const
+      {
+         return matrix;
+      }
+
+      NeighborCountsArray getEntityCornerCounts() const
+      {
+         NeighborCountsArray counts( getEntitiesCount() );
+         counts.setValue( cornersCount );
+         return counts;
+      }
+
+      bool empty() const
+      {
+         return getEntitiesCount() == 0;
+      }
+
+      EntitySeedMatrixSeed getSeed( const GlobalIndexType& entityIndex )
+      {
+         return EntitySeedMatrixSeed( matrix.getRow( entityIndex ) );
+      }
+
+      ConstEntitySeedMatrixSeed getSeed( const GlobalIndexType& entityIndex ) const
+      {
+         return ConstEntitySeedMatrixSeed( matrix.getRow( entityIndex ) );
+      }
+
+   private:
+      SubentityMatrixType matrix;
+};
+
+template< typename MeshConfig,
+          typename EntityTopology >
+class EntitySeedMatrix< MeshConfig, EntityTopology, true >
+{
+   using MeshTraitsType = MeshTraits< MeshConfig, Devices::Host >;
+
+   public:
+      using GlobalIndexType = typename MeshTraitsType::GlobalIndexType;
+      using LocalIndexType  = typename MeshTraitsType::LocalIndexType;
+      using SubentityMatrixType = typename MeshTraitsType::template SubentityMatrixType< EntityTopology::dimension >;
+      using NeighborCountsArray = typename MeshTraitsType::NeighborCountsArray;
+
+      class EntitySeedMatrixSeed
+      {
+         using RowView = typename SubentityMatrixType::RowView;
+
+         public:
+            EntitySeedMatrixSeed( const RowView& matrixRow, const LocalIndexType& corners )
+            : row( matrixRow ),
+              cornersCount( corners )
+            {}
+
+            LocalIndexType getCornersCount() const
+            {
+               return cornersCount;
+            }
+
+            void setCornerId( const LocalIndexType& cornerIndex, const GlobalIndexType& pointIndex )
+            {
+               TNL_ASSERT_GE( cornerIndex, 0, "corner index must be non-negative" );
+               TNL_ASSERT_LT( cornerIndex, getCornersCount(), "corner index is out of bounds" );
+               TNL_ASSERT_GE( pointIndex, 0, "point index must be non-negative" );
+               this->row.setColumnIndex( cornerIndex, pointIndex );
+            }
+
+            GlobalIndexType getCornerId( const LocalIndexType& cornerIndex ) const
+            {
+               return this->row.getColumnIndex( cornerIndex );
+            }
+
+         private:
+            RowView row;
+            LocalIndexType cornersCount;
+      };
+
+      class ConstEntitySeedMatrixSeed
+      {
+         using ConstRowView = typename SubentityMatrixType::ConstRowView;
+
+         public:
+            ConstEntitySeedMatrixSeed( const ConstRowView& matrixRow, const LocalIndexType& corners )
+            : row( matrixRow ),
+              cornersCount( corners )
+            {}
+
+            LocalIndexType getCornersCount() const
+            {
+               return cornersCount;
+            }
+
+            GlobalIndexType getCornerId( const LocalIndexType& cornerIndex ) const
+            {
+               return this->row.getColumnIndex( cornerIndex );
+            }
+
+         private:
+            ConstRowView row;
+            LocalIndexType cornersCount;
+      };
+
+      void setDimensions( const GlobalIndexType& entitiesCount, const GlobalIndexType& pointsCount )
+      {
+         counts.setSize( entitiesCount );
+         matrix.setDimensions( entitiesCount, pointsCount );
+      }
+
+      void setEntityCornersCount( const GlobalIndexType& entityIndex, const LocalIndexType& count )
+      {
+         counts.setElement( entityIndex, count );
+      }
+
+      void initializeRows()
+      {
+         matrix.setRowCapacities( counts );
+      }
+
+      void reset()
+      {
+         matrix.reset();
+         counts.reset();
+      }
+
+      void setSeedIndex( const GlobalIndexType& entityIndex, const LocalIndexType& localIndex, const GlobalIndexType& globalIndex )
+      {
+         matrix.getRow( entityIndex ).setElement( localIndex, globalIndex, true );
+      }
+
+      GlobalIndexType getEntitiesCount() const
+      {
+         return matrix.getRows();
+      }
+
+      LocalIndexType getEntityCornersCount( const GlobalIndexType& entityIndex ) const
+      {
+         return counts.getElement( entityIndex );
+      }
+
+      GlobalIndexType getSeedIndex( const GlobalIndexType& entityIndex, const LocalIndexType& localIndex ) const
+      {
+         return matrix.getRow( entityIndex ).getColumnIndex( localIndex );
+      }
+
+      SubentityMatrixType& getMatrix()
+      {
+         return matrix;
+      }
+
+      const SubentityMatrixType& getMatrix() const
+      {
+         return matrix;
+      }
+
+      NeighborCountsArray& getEntityCornerCounts()
+      {
+         return counts;
+      }
+
+      const NeighborCountsArray& getEntityCornerCounts() const
+      {
+         return counts;
+      }
+
+      bool empty() const
+      {
+         return getEntitiesCount() == 0;
+      }
+
+      EntitySeedMatrixSeed getSeed( const GlobalIndexType& entityIndex )
+      {
+         return EntitySeedMatrixSeed( matrix.getRow( entityIndex ), counts[ entityIndex ] );
+      }
+
+      ConstEntitySeedMatrixSeed getSeed( const GlobalIndexType& entityIndex ) const
+      {
+         return ConstEntitySeedMatrixSeed( matrix.getRow( entityIndex ), counts[ entityIndex ] );
+      }
+
+   private:
+      SubentityMatrixType matrix;
+      NeighborCountsArray counts;
+};
+
+} // namespace Meshes
+} // namespace TNL
\ No newline at end of file
diff --git a/src/TNL/Meshes/MeshDetails/initializer/Initializer.h b/src/TNL/Meshes/MeshDetails/initializer/Initializer.h
index a73fdbfe24..ef840d2b81 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/Initializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/Initializer.h
@@ -78,7 +78,7 @@ class Initializer
       using BaseType          = InitializerLayer< MeshConfig, DimensionTag >;
       using PointArrayType    = typename MeshTraitsType::PointArrayType;
       using CellSeedArrayType = typename MeshTraitsType::CellSeedArrayType;
-      using FaceSeedArrayType = typename MeshTraitsType::FaceSeedArrayType;
+      using FaceSeedMatrixType = typename MeshTraitsType::FaceSeedMatrixType;
       using GlobalIndexType   = typename MeshTraitsType::GlobalIndexType;
       using LocalIndexType    = typename MeshTraitsType::LocalIndexType;
       using NeighborCountsArray = typename MeshTraitsType::NeighborCountsArray;
@@ -88,7 +88,7 @@ class Initializer
 
       // The points and cellSeeds arrays will be reset when not needed to save memory.
       void createMesh( PointArrayType& points,
-                       FaceSeedArrayType& faceSeeds,
+                       FaceSeedMatrixType& faceSeeds,
                        CellSeedArrayType& cellSeeds,
                        MeshType& mesh )
       {
@@ -116,6 +116,12 @@ class Initializer
          auto& matrix = mesh->template getSubentitiesMatrix< Dimension, Subdimension >();
          matrix.setDimensions( capacities.getSize(), subentitiesCount );
          matrix.setRowCapacities( capacities );
+         initSubentitiesCounts< Dimension, Subdimension >( capacities );
+      }
+
+      template< int Dimension, int Subdimension >
+      void initSubentitiesCounts( const NeighborCountsArray& capacities )
+      {
          mesh->template setSubentitiesCounts< Dimension, Subdimension >( std::move( capacities ) );
       }
 
@@ -148,6 +154,14 @@ class Initializer
          return mesh->template getSubentitiesCount< Dimension, 0 >( entityIndex );
       }
 
+      template< int Dimension, int Subdimension >
+      auto
+      getSubentitiesMatrix()
+         -> decltype( this->mesh->template getSubentitiesMatrix< Dimension, Subdimension >() )
+      {
+         return mesh->template getSubentitiesMatrix< Dimension, Subdimension >();
+      }
+
       template< int Dimension, int Superdimension >
       auto
       getSuperentitiesCountsArray()
@@ -194,7 +208,7 @@ protected:
    using InitializerType       = Initializer< MeshConfig >;
    using EntityInitializerType = EntityInitializer< MeshConfig, EntityTopology >;
    using CellSeedArrayType     = typename MeshTraitsType::CellSeedArrayType;
-   using FaceSeedArrayType     = typename MeshTraitsType::FaceSeedArrayType;
+   using FaceSeedMatrixType    = typename MeshTraitsType::FaceSeedMatrixType;
    using NeighborCountsArray   = typename MeshTraitsType::NeighborCountsArray;
 
    public:
@@ -218,7 +232,7 @@ protected:
          BaseType::initEntities( initializer, mesh );
       }
 
-      void initEntities( InitializerType& initializer, FaceSeedArrayType& faceSeeds, MeshType& mesh )
+      void initEntities( InitializerType& initializer, FaceSeedMatrixType& faceSeeds, MeshType& mesh )
       {
          //std::cout << " Initiating entities with dimension " << DimensionTag::value << " ... " << std::endl;
          initializer.template setEntitiesCount< DimensionTag::value >( initializer.getCellSeeds().getSize() );
@@ -252,7 +266,7 @@ protected:
    using SeedType              = EntitySeed< MeshConfig, EntityTopology >;
    using SeedIndexedSet        = typename MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::SeedIndexedSetType;
    using CellSeedArrayType     = typename MeshTraitsType::CellSeedArrayType;
-   using EntitySeedArrayType   = Containers::Array< SeedType, typename MeshTraitsType::DeviceType, GlobalIndexType >;
+   using FaceSeedMatrixType    = typename MeshTraitsType::FaceSeedMatrixType;
    using NeighborCountsArray   = typename MeshTraitsType::NeighborCountsArray;
    
    public:
@@ -307,23 +321,13 @@ protected:
          BaseType::initEntities( initializer, mesh );
       }
 
-      void initEntities( InitializerType& initializer, EntitySeedArrayType& seeds, MeshType& mesh )
+      void initEntities( InitializerType& initializer, FaceSeedMatrixType& faceSeeds, MeshType& mesh )
       {
          //std::cout << " Initiating entities with dimension " << DimensionTag::value << " ... " << std::endl;
 
-         initializer.template setEntitiesCount< DimensionTag::value >( seeds.getSize() );
+         initializer.template setEntitiesCount< DimensionTag::value >( faceSeeds.getEntitiesCount() );
 
-         // allocate the subvertex matrix
-         NeighborCountsArray capacities( seeds.getSize() );
-         for( GlobalIndexType i = 0; i < capacities.getSize(); i++ ) {
-            capacities.setElement( i, seeds[ i ].getCornersCount() );
-         }
-         EntityInitializerType::initSubvertexMatrix( capacities, initializer );
-
-         // initialize the entities
-         for( GlobalIndexType i = 0; i < seeds.getSize(); i++ )
-            EntityInitializerType::initEntity( i, seeds[ i ], initializer );
-         seeds.reset();
+         EntityInitializerType::initSubvertexMatrix( faceSeeds, initializer );
 
          // initialize links between the entities and all superentities
          EntityInitializerType::initSuperentities( initializer, mesh );
@@ -354,7 +358,7 @@ class InitializerLayer< MeshConfig, DimensionTag< 0 > >
    using InitializerType       = Initializer< MeshConfig >;
    using EntityInitializerType = EntityInitializer< MeshConfig, EntityTopology >;
    using SeedType              = EntitySeed< MeshConfig, EntityTopology >;
-   using EntitySeedArrayType   = Containers::Array< SeedType, typename MeshTraitsType::DeviceType, GlobalIndexType >;
+   using FaceSeedMatrixType    = typename MeshTraitsType::FaceSeedMatrixType;
 
    public:
 
@@ -370,7 +374,7 @@ class InitializerLayer< MeshConfig, DimensionTag< 0 > >
       }
 
       // This overload is only here for compatibility with Polyhedrons, it is never called
-      void initEntities( InitializerType& initializer, EntitySeedArrayType& faceSeeds, MeshType& mesh )
+      void initEntities( InitializerType& initializer, FaceSeedMatrixType& faceSeeds, MeshType& mesh )
       {
       }
 };
diff --git a/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h b/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
index db54ac8278..f2c4c8d588 100644
--- a/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
+++ b/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
@@ -48,7 +48,7 @@ public:
    using EntityTopology                = typename EntityTopologyGetter< MeshConfig, DimensionTag< Dimension > >::Topology;
    using EntityType                    = MeshEntity< MeshConfig, Device, EntityTopology >;
    using SeedType                      = EntitySeed< MeshConfig, EntityTopology >;
-
+   
    using SeedIndexedSetType            = Containers::UnorderedIndexedSet< SeedType, GlobalIndexType, typename SeedType::HashType, typename SeedType::KeyEqual >;
    using SeedSetType                   = std::unordered_set< typename SeedIndexedSetType::key_type, typename SeedIndexedSetType::hasher, typename SeedIndexedSetType::key_equal >;
 
@@ -75,7 +75,7 @@ public:
    using EntityTopology                = typename EntityTopologyGetter< MeshConfig, DimensionTag< Dimension > >::Topology;
    using EntityType                    = MeshEntity< MeshConfig, Device, EntityTopology >;
    using SeedType                      = EntitySeed< MeshConfig, EntityTopology >;
-
+   
    using SeedIndexedSetType            = Containers::UnorderedIndexedSet< SeedType, GlobalIndexType, typename SeedType::HashType, typename SeedType::KeyEqual >;
    using SeedSetType                   = std::unordered_set< typename SeedIndexedSetType::key_type, typename SeedIndexedSetType::hasher, typename SeedIndexedSetType::key_equal >;
 
diff --git a/src/TNL/Meshes/MeshDetails/traits/MeshTraits.h b/src/TNL/Meshes/MeshDetails/traits/MeshTraits.h
index df079e40b3..4f4d328f2c 100644
--- a/src/TNL/Meshes/MeshDetails/traits/MeshTraits.h
+++ b/src/TNL/Meshes/MeshDetails/traits/MeshTraits.h
@@ -19,6 +19,7 @@
 #include <TNL/Containers/StaticVector.h>
 #include <TNL/Containers/Array.h>
 #include <TNL/Matrices/SparseMatrix.h>
+#include <TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h>
 #include <TNL/Algorithms/Segments/Ellpack.h>
 #include <TNL/Algorithms/Segments/SlicedEllpack.h>
 #include <TNL/Meshes/DimensionTag.h>
@@ -96,6 +97,9 @@ public:
    using PointArrayType      = Containers::Array< PointType, DeviceType, GlobalIndexType >;
    using FaceSeedArrayType   = Containers::Array< FaceSeedType, DeviceType, GlobalIndexType >;
    using CellSeedArrayType   = Containers::Array< CellSeedType, DeviceType, GlobalIndexType >;
+   using FaceSeedMatrixType  = EntitySeedMatrix< MeshConfig, FaceTopology >;
+   using CellSeedMatrixType  = EntitySeedMatrix< MeshConfig, CellTopology >;
+
    using EntityTagsArrayType = Containers::Array< EntityTagType, DeviceType, GlobalIndexType >;
 
    template< int Dimension >
diff --git a/src/TNL/Meshes/Readers/MeshReader.h b/src/TNL/Meshes/Readers/MeshReader.h
index f1188de71a..ee23cb35b1 100644
--- a/src/TNL/Meshes/Readers/MeshReader.h
+++ b/src/TNL/Meshes/Readers/MeshReader.h
@@ -197,11 +197,19 @@ public:
                // let's just assume that the connectivity and offsets arrays have the same type...
                using mpark::get;
                const auto& offsets = get< std::decay_t<decltype(connectivity)> >( faceOffsetsArray );
+               
                std::size_t offsetStart = 0;
                for( std::size_t i = 0; i < NumberOfFaces; i++ ) {
-                  FaceSeedType& seed = meshBuilder.getFaceSeed( i );
                   const std::size_t offsetEnd = offsets[ i ];
-                  seed.setCornersCount( offsetEnd - offsetStart );
+                  meshBuilder.setFaceCornersCount( i, offsetEnd - offsetStart );
+                  offsetStart = offsetEnd;
+               }
+               meshBuilder.initializeFaceSeeds();
+
+               offsetStart = 0;
+               for( std::size_t i = 0; i < NumberOfFaces; i++ ) {
+                  auto seed = meshBuilder.getFaceSeed( i );
+                  const std::size_t offsetEnd = offsets[ i ];
                   for( std::size_t o = offsetStart; o < offsetEnd; o++ )
                      seed.setCornerId( o - offsetStart, connectivity[ o ] );
                   offsetStart = offsetEnd;
diff --git a/src/UnitTests/Meshes/MeshGeometryTest.h b/src/UnitTests/Meshes/MeshGeometryTest.h
index 2eee22790d..a87932b9c7 100644
--- a/src/UnitTests/Meshes/MeshGeometryTest.h
+++ b/src/UnitTests/Meshes/MeshGeometryTest.h
@@ -266,53 +266,54 @@ TEST( MeshGeometryTest, PolyhedronAreaTest )
    meshBuilder.setPoint(  8, point8 );
 
    meshBuilder.setFacesCount( 9 );
+   meshBuilder.setFaceCornersCount( 0, 4 );
+   meshBuilder.setFaceCornersCount( 1, 4 );
+   meshBuilder.setFaceCornersCount( 2, 4 );
+   meshBuilder.setFaceCornersCount( 3, 4 );
+   meshBuilder.setFaceCornersCount( 4, 4 );
+   meshBuilder.setFaceCornersCount( 5, 3 );
+   meshBuilder.setFaceCornersCount( 6, 3 );
+   meshBuilder.setFaceCornersCount( 7, 3 );
+   meshBuilder.setFaceCornersCount( 8, 3 );
+   meshBuilder.initializeFaceSeeds();
 
-   meshBuilder.getFaceSeed( 0 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 0, 2 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 1, 3 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 2, 1 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 3, 0 );
 
-   meshBuilder.getFaceSeed( 1 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 0, 1 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 1, 3 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 2, 7 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 3, 5 );
 
-   meshBuilder.getFaceSeed( 2 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 0, 2 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 1, 0 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 2, 4 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 3, 6 );
 
-   meshBuilder.getFaceSeed( 3 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 0, 0 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 1, 1 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 2, 5 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 3, 4 );
 
-   meshBuilder.getFaceSeed( 4 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 0, 3 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 1, 2 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 2, 6 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 3, 7 );
 
-   meshBuilder.getFaceSeed( 5 ).setCornersCount( 3 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 0, 4 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 1, 5 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 2, 8 );
 
-   meshBuilder.getFaceSeed( 6 ).setCornersCount( 3 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 0, 5 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 2, 8 );
 
-   meshBuilder.getFaceSeed( 7 ).setCornersCount( 3 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 0, 7 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 1, 6 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 2, 8 );
 
-   meshBuilder.getFaceSeed( 8 ).setCornersCount( 3 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 0, 6 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 1, 4 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 2, 8 );
@@ -651,9 +652,25 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
     */
 
    meshBuilder.setFacesCount( 16 );
+   meshBuilder.setFaceCornersCount(  0, 5 );
+   meshBuilder.setFaceCornersCount(  1, 4 );
+   meshBuilder.setFaceCornersCount(  2, 5 );
+   meshBuilder.setFaceCornersCount(  3, 4 );
+   meshBuilder.setFaceCornersCount(  4, 5 );
+   meshBuilder.setFaceCornersCount(  5, 4 );
+   meshBuilder.setFaceCornersCount(  6, 5 );
+   meshBuilder.setFaceCornersCount(  7, 5 );
+   meshBuilder.setFaceCornersCount(  8, 5 );
+   meshBuilder.setFaceCornersCount(  9, 5 );
+   meshBuilder.setFaceCornersCount( 10, 5 );
+   meshBuilder.setFaceCornersCount( 11, 6 );
+   meshBuilder.setFaceCornersCount( 12, 3 );
+   meshBuilder.setFaceCornersCount( 13, 4 );
+   meshBuilder.setFaceCornersCount( 14, 4 );
+   meshBuilder.setFaceCornersCount( 15, 5 );
+   meshBuilder.initializeFaceSeeds();
 
    //   0     1     2     3     4
-   meshBuilder.getFaceSeed( 0 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 2, 2 );
@@ -661,14 +678,12 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 0 ).setCornerId( 4, 4 );
 
    //   4     3     5     6
-   meshBuilder.getFaceSeed( 1 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 0, 4 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 1, 3 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 2, 5 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 3, 6 );
 
    //   5     3     2     7     8
-   meshBuilder.getFaceSeed( 2 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 0, 5 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 1, 3 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 2, 2 );
@@ -676,14 +691,12 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 2 ).setCornerId( 4, 8 );
 
    //   9     1     0    10
-   meshBuilder.getFaceSeed( 3 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 0, 9 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 1, 1 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 2, 0 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 3, 10 );
 
    //  11     7     2     1     9
-   meshBuilder.getFaceSeed( 4 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 0, 11 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 2, 2 );
@@ -691,14 +704,12 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 4 ).setCornerId( 4, 9 );
 
    //   8     7    11    12
-   meshBuilder.getFaceSeed( 5 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 0, 8 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 2, 11 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 3, 12 );
 
    //  13    12    11     9    10
-   meshBuilder.getFaceSeed( 6 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 1, 12 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 2, 11 );
@@ -706,7 +717,6 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 6 ).setCornerId( 4, 10 );
 
    //  13    10     0     4     6
-   meshBuilder.getFaceSeed( 7 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 1, 10 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 2, 0 );
@@ -714,7 +724,6 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 7 ).setCornerId( 4, 6 );
 
    //  13     6     5     8    12
-   meshBuilder.getFaceSeed( 8 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 1, 6 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 2, 5 );
@@ -722,7 +731,6 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 8 ).setCornerId( 4, 12 );
 
    //   8     7    14    15    16
-   meshBuilder.getFaceSeed( 9 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 0, 8 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 2, 14 );
@@ -730,7 +738,6 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 9 ).setCornerId( 4, 16 );
 
    //  16    15    17    18    19
-   meshBuilder.getFaceSeed( 10 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 0, 16 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 1, 15 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 2, 17 );
@@ -738,7 +745,6 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 10 ).setCornerId( 4, 19 );
 
    //  20    18    17    14     7    11
-   meshBuilder.getFaceSeed( 11 ).setCornersCount( 6 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 0, 20 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 1, 18 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 2, 17 );
@@ -747,27 +753,23 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getFaceSeed( 11 ).setCornerId( 5, 11 );
 
    //  17    15    14
-   meshBuilder.getFaceSeed( 12 ).setCornersCount( 3 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 0, 17 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 1, 15 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 2, 14 );
 
    //  21    19    18    20
-   meshBuilder.getFaceSeed( 13 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 0, 21 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 1, 19 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 2, 18 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 3, 20 );
 
    //  21    20    11    12
-   meshBuilder.getFaceSeed( 14 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 0, 21 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 1, 20 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 2, 11 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 3, 12 );
 
    //  12     8    16    19    21
-   meshBuilder.getFaceSeed( 15 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 0, 12 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 1, 8 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 2, 16 );
@@ -1009,9 +1011,25 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
     */
 
    meshBuilder.setFacesCount( 16 );
+   meshBuilder.setFaceCornersCount(  0, 5 );
+   meshBuilder.setFaceCornersCount(  1, 4 );
+   meshBuilder.setFaceCornersCount(  2, 5 );
+   meshBuilder.setFaceCornersCount(  3, 4 );
+   meshBuilder.setFaceCornersCount(  4, 5 );
+   meshBuilder.setFaceCornersCount(  5, 4 );
+   meshBuilder.setFaceCornersCount(  6, 5 );
+   meshBuilder.setFaceCornersCount(  7, 5 );
+   meshBuilder.setFaceCornersCount(  8, 5 );
+   meshBuilder.setFaceCornersCount(  9, 5 );
+   meshBuilder.setFaceCornersCount( 10, 5 );
+   meshBuilder.setFaceCornersCount( 11, 6 );
+   meshBuilder.setFaceCornersCount( 12, 3 );
+   meshBuilder.setFaceCornersCount( 13, 4 );
+   meshBuilder.setFaceCornersCount( 14, 4 );
+   meshBuilder.setFaceCornersCount( 15, 5 );
+   meshBuilder.initializeFaceSeeds();
 
    //   0     1     2     3     4
-   meshBuilder.getFaceSeed( 0 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 2, 2 );
@@ -1019,14 +1037,12 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 0 ).setCornerId( 4, 4 );
 
    //   4     3     5     6
-   meshBuilder.getFaceSeed( 1 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 0, 4 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 1, 3 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 2, 5 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 3, 6 );
 
    //   5     3     2     7     8
-   meshBuilder.getFaceSeed( 2 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 0, 5 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 1, 3 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 2, 2 );
@@ -1034,14 +1050,12 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 2 ).setCornerId( 4, 8 );
 
    //   9     1     0    10
-   meshBuilder.getFaceSeed( 3 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 0, 9 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 1, 1 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 2, 0 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 3, 10 );
 
    //  11     7     2     1     9
-   meshBuilder.getFaceSeed( 4 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 0, 11 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 2, 2 );
@@ -1049,14 +1063,12 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 4 ).setCornerId( 4, 9 );
 
    //   8     7    11    12
-   meshBuilder.getFaceSeed( 5 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 0, 8 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 2, 11 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 3, 12 );
 
    //  13    12    11     9    10
-   meshBuilder.getFaceSeed( 6 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 1, 12 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 2, 11 );
@@ -1064,7 +1076,6 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 6 ).setCornerId( 4, 10 );
 
    //  13    10     0     4     6
-   meshBuilder.getFaceSeed( 7 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 1, 10 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 2, 0 );
@@ -1072,7 +1083,6 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 7 ).setCornerId( 4, 6 );
 
    //  13     6     5     8    12
-   meshBuilder.getFaceSeed( 8 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 1, 6 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 2, 5 );
@@ -1080,7 +1090,6 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 8 ).setCornerId( 4, 12 );
 
    //   8     7    14    15    16
-   meshBuilder.getFaceSeed( 9 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 0, 8 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 2, 14 );
@@ -1088,7 +1097,6 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 9 ).setCornerId( 4, 16 );
 
    //  16    15    17    18    19
-   meshBuilder.getFaceSeed( 10 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 0, 16 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 1, 15 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 2, 17 );
@@ -1096,7 +1104,6 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 10 ).setCornerId( 4, 19 );
 
    //  20    18    17    14     7    11
-   meshBuilder.getFaceSeed( 11 ).setCornersCount( 6 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 0, 20 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 1, 18 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 2, 17 );
@@ -1105,27 +1112,23 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getFaceSeed( 11 ).setCornerId( 5, 11 );
 
    //  17    15    14
-   meshBuilder.getFaceSeed( 12 ).setCornersCount( 3 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 0, 17 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 1, 15 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 2, 14 );
 
    //  21    19    18    20
-   meshBuilder.getFaceSeed( 13 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 0, 21 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 1, 19 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 2, 18 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 3, 20 );
 
    //  21    20    11    12
-   meshBuilder.getFaceSeed( 14 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 0, 21 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 1, 20 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 2, 11 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 3, 12 );
 
    //  12     8    16    19    21
-   meshBuilder.getFaceSeed( 15 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 0, 12 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 1, 8 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 2, 16 );
diff --git a/src/UnitTests/Meshes/MeshTest.h b/src/UnitTests/Meshes/MeshTest.h
index 040eb07e9b..4ba992bf08 100644
--- a/src/UnitTests/Meshes/MeshTest.h
+++ b/src/UnitTests/Meshes/MeshTest.h
@@ -1069,26 +1069,15 @@ TEST( MeshTest, TwoPolygonsTest )
    meshBuilder.setCellsCount( 2 );
 
    meshBuilder.getCellSeed( 0 ).setCornersCount( 4 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 0 ).getCornersCount(), 4 );
-
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 3, 3 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 0 ).getCornerIds() [ 0 ], 0 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 0 ).getCornerIds() [ 1 ], 1 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 0 ).getCornerIds() [ 2 ], 2 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 0 ).getCornerIds() [ 3 ], 3 );
 
    meshBuilder.getCellSeed( 1 ).setCornersCount( 3 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 1 ).getCornersCount(), 3 );
-
    meshBuilder.getCellSeed( 1 ).setCornerId( 0, 3 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1, 2 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2, 4 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 1 ).getCornerIds() [ 0 ], 3 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 1 ).getCornerIds() [ 1 ], 2 );
-   EXPECT_EQ( meshBuilder.getCellSeed( 1 ).getCornerIds() [ 2 ], 4 );
 
    ASSERT_TRUE( meshBuilder.build( mesh ) );
 
@@ -2652,9 +2641,25 @@ TEST( MeshTest, TwoPolyhedronsTest )
     */
 
    meshBuilder.setFacesCount( 16 );
+   meshBuilder.setFaceCornersCount(  0, 5 );
+   meshBuilder.setFaceCornersCount(  1, 4 );
+   meshBuilder.setFaceCornersCount(  2, 5 );
+   meshBuilder.setFaceCornersCount(  3, 4 );
+   meshBuilder.setFaceCornersCount(  4, 5 );
+   meshBuilder.setFaceCornersCount(  5, 4 );
+   meshBuilder.setFaceCornersCount(  6, 5 );
+   meshBuilder.setFaceCornersCount(  7, 5 );
+   meshBuilder.setFaceCornersCount(  8, 5 );
+   meshBuilder.setFaceCornersCount(  9, 5 );
+   meshBuilder.setFaceCornersCount( 10, 5 );
+   meshBuilder.setFaceCornersCount( 11, 6 );
+   meshBuilder.setFaceCornersCount( 12, 3 );
+   meshBuilder.setFaceCornersCount( 13, 4 );
+   meshBuilder.setFaceCornersCount( 14, 4 );
+   meshBuilder.setFaceCornersCount( 15, 5 );
+   meshBuilder.initializeFaceSeeds();
 
    //   0     1     2     3     4
-   meshBuilder.getFaceSeed( 0 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getFaceSeed( 0 ).setCornerId( 2, 2 );
@@ -2662,14 +2667,12 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 0 ).setCornerId( 4, 4 );
 
    //   4     3     5     6
-   meshBuilder.getFaceSeed( 1 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 0, 4 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 1, 3 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 2, 5 );
    meshBuilder.getFaceSeed( 1 ).setCornerId( 3, 6 );
 
    //   5     3     2     7     8
-   meshBuilder.getFaceSeed( 2 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 0, 5 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 1, 3 );
    meshBuilder.getFaceSeed( 2 ).setCornerId( 2, 2 );
@@ -2677,14 +2680,12 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 2 ).setCornerId( 4, 8 );
 
    //   9     1     0    10
-   meshBuilder.getFaceSeed( 3 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 0, 9 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 1, 1 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 2, 0 );
    meshBuilder.getFaceSeed( 3 ).setCornerId( 3, 10 );
 
    //  11     7     2     1     9
-   meshBuilder.getFaceSeed( 4 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 0, 11 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 4 ).setCornerId( 2, 2 );
@@ -2692,14 +2693,12 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 4 ).setCornerId( 4, 9 );
 
    //   8     7    11    12
-   meshBuilder.getFaceSeed( 5 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 0, 8 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 2, 11 );
    meshBuilder.getFaceSeed( 5 ).setCornerId( 3, 12 );
 
    //  13    12    11     9    10
-   meshBuilder.getFaceSeed( 6 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 1, 12 );
    meshBuilder.getFaceSeed( 6 ).setCornerId( 2, 11 );
@@ -2707,7 +2706,6 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 6 ).setCornerId( 4, 10 );
 
    //  13    10     0     4     6
-   meshBuilder.getFaceSeed( 7 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 1, 10 );
    meshBuilder.getFaceSeed( 7 ).setCornerId( 2, 0 );
@@ -2715,7 +2713,6 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 7 ).setCornerId( 4, 6 );
 
    //  13     6     5     8    12
-   meshBuilder.getFaceSeed( 8 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 0, 13 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 1, 6 );
    meshBuilder.getFaceSeed( 8 ).setCornerId( 2, 5 );
@@ -2723,7 +2720,6 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 8 ).setCornerId( 4, 12 );
 
    //   8     7    14    15    16
-   meshBuilder.getFaceSeed( 9 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 0, 8 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 1, 7 );
    meshBuilder.getFaceSeed( 9 ).setCornerId( 2, 14 );
@@ -2731,7 +2727,6 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 9 ).setCornerId( 4, 16 );
 
    //  16    15    17    18    19
-   meshBuilder.getFaceSeed( 10 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 0, 16 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 1, 15 );
    meshBuilder.getFaceSeed( 10 ).setCornerId( 2, 17 );
@@ -2739,7 +2734,6 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 10 ).setCornerId( 4, 19 );
 
    //  20    18    17    14     7    11
-   meshBuilder.getFaceSeed( 11 ).setCornersCount( 6 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 0, 20 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 1, 18 );
    meshBuilder.getFaceSeed( 11 ).setCornerId( 2, 17 );
@@ -2748,27 +2742,23 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getFaceSeed( 11 ).setCornerId( 5, 11 );
 
    //  17    15    14
-   meshBuilder.getFaceSeed( 12 ).setCornersCount( 3 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 0, 17 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 1, 15 );
    meshBuilder.getFaceSeed( 12 ).setCornerId( 2, 14 );
 
    //  21    19    18    20
-   meshBuilder.getFaceSeed( 13 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 0, 21 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 1, 19 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 2, 18 );
    meshBuilder.getFaceSeed( 13 ).setCornerId( 3, 20 );
 
    //  21    20    11    12
-   meshBuilder.getFaceSeed( 14 ).setCornersCount( 4 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 0, 21 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 1, 20 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 2, 11 );
    meshBuilder.getFaceSeed( 14 ).setCornerId( 3, 12 );
 
    //  12     8    16    19    21
-   meshBuilder.getFaceSeed( 15 ).setCornersCount( 5 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 0, 12 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 1, 8 );
    meshBuilder.getFaceSeed( 15 ).setCornerId( 2, 16 );
-- 
GitLab