diff --git a/src/TNL/Meshes/Geometry/getDecomposedMesh.h b/src/TNL/Meshes/Geometry/getDecomposedMesh.h
index beddfdee18fc183f708117221514a5ec90f0926a..6c51c8884e08d8f52c49c55e41de824812a0f50d 100644
--- a/src/TNL/Meshes/Geometry/getDecomposedMesh.h
+++ b/src/TNL/Meshes/Geometry/getDecomposedMesh.h
@@ -70,7 +70,7 @@ getDecomposedMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
    // Lambda for setting decomposed triangle in meshBuilder
    GlobalIndexType setCellsCount = 0;
    auto setDecomposedCellFunc = [&] ( GlobalIndexType v0, GlobalIndexType v1, GlobalIndexType v2 ) {
-      auto & entitySeed = meshBuilder.getCellSeed( setCellsCount++ );
+      auto entitySeed = meshBuilder.getCellSeed( setCellsCount++ );
       entitySeed.setCornerId( 0, v0 );
       entitySeed.setCornerId( 1, v1 );
       entitySeed.setCornerId( 2, v2 );
@@ -142,7 +142,7 @@ getDecomposedMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
    // Lambda for setting decomposed cells in meshBuilder
    GlobalIndexType setCellsCount = 0;
    auto setDecomposedCellFunc = [&] ( GlobalIndexType v0, GlobalIndexType v1, GlobalIndexType v2, GlobalIndexType v3 ) {
-      auto & entitySeed = meshBuilder.getCellSeed( setCellsCount++ );
+      auto entitySeed = meshBuilder.getCellSeed( setCellsCount++ );
       entitySeed.setCornerId( 0, v0 );
       entitySeed.setCornerId( 1, v1 );
       entitySeed.setCornerId( 2, v2 );
diff --git a/src/TNL/Meshes/Geometry/getPlanarMesh.h b/src/TNL/Meshes/Geometry/getPlanarMesh.h
index e27118374349261ab29416ebca4c9ce0ccfa9885..919eae67d35f7cdb4dbcf46aec87bc803eb65ed0 100644
--- a/src/TNL/Meshes/Geometry/getPlanarMesh.h
+++ b/src/TNL/Meshes/Geometry/getPlanarMesh.h
@@ -27,6 +27,7 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
    using LocalIndexType = typename PolygonMesh::LocalIndexType;
    using PointType = typename PolygonMesh::PointType;
    using RealType = typename PolygonMesh::RealType;
+   using BoolVector = Containers::Vector< bool, Devices::Host, GlobalIndexType >;
    using EntityDecomposer = EntityDecomposer< MeshConfig, Topologies::Polygon, EntityDecomposerVersion_ >;
 
    constexpr RealType precision{ 1e-6 };
@@ -37,12 +38,17 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
    const GlobalIndexType inPointsCount = inMesh.template getEntitiesCount< 0 >();
    const GlobalIndexType inCellsCount = inMesh.template getEntitiesCount< 2 >();
 
-   // find the number of points and cells in the outMesh
+   BoolVector planarCache;
+   planarCache.setSize( inCellsCount );
+
+   // Count the number of points and cells in the outMesh
    GlobalIndexType outPointsCount = inPointsCount;
    GlobalIndexType outCellsCount = 0;
    for( GlobalIndexType i = 0; i < inCellsCount; i++ ) {
       const auto cell = inMesh.template getEntity< 2 >( i );
-      if( isPlanar( inMesh, cell, precision ) ) { // Cell is not decomposed
+      const bool planar = isPlanar( inMesh, cell, precision );
+      planarCache.setElement( i, planar );
+      if( planar ) { // Cell is not decomposed
          outCellsCount++;
       }
       else { // Cell is decomposed
@@ -62,31 +68,48 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
    }
 
    // Lambda for creating new points
-   auto createPointFunc = [&] ( const PointType & point ) {
+   auto createPointFunc = [&] ( const PointType& point ) {
       const auto pointIdx = setPointsCount++;
       meshBuilder.setPoint( pointIdx, point );
       return pointIdx;
    };
 
-   // Lambda for setting decomposed cells in meshBuilder
+   // set corner counts for cells
+   for( GlobalIndexType i = 0, o = 0; i < inCellsCount; i++ ) {
+      const auto cell = inMesh.template getEntity< 2 >( i );
+      const bool planar = planarCache[ i ];
+      if( planar ) { // Copy planar cells
+         const auto verticesCount = cell.template getSubentitiesCount< 0 >();
+         meshBuilder.setCellCornersCount( o++, verticesCount );
+      }
+      else { // Decompose non-planar cells
+         GlobalIndexType entitiesCount;
+         std::tie( std::ignore, entitiesCount ) = EntityDecomposer::getExtraPointsAndEntitiesCount( cell );
+         for( GlobalIndexType j = 0; j < entitiesCount; j++ ) {
+            meshBuilder.setCellCornersCount( o++, 3 );
+         }
+      }
+   }
+   meshBuilder.initializeCellSeeds();
+
+   // Lambda for setting corner ids of decomposed cells
    GlobalIndexType setCellsCount = 0;
    auto setDecomposedCellFunc = [&] ( GlobalIndexType v0, GlobalIndexType v1, GlobalIndexType v2 ) {
-      auto & entitySeed = meshBuilder.getCellSeed( setCellsCount++ );
-      entitySeed.setCornersCount( 3 );
-      entitySeed.setCornerId( 0, v0 );
-      entitySeed.setCornerId( 1, v1 );
-      entitySeed.setCornerId( 2, v2 );
+      auto seed = meshBuilder.getCellSeed( setCellsCount++ );
+      seed.setCornerId( 0, v0 );
+      seed.setCornerId( 1, v1 );
+      seed.setCornerId( 2, v2 );
    };
 
    // Decompose non-planar cells and copy the rest
    for( GlobalIndexType i = 0; i < inCellsCount; i++ ) {
       const auto cell = inMesh.template getEntity< 2 >( i );
-      if( isPlanar( inMesh, cell, precision ) ) { // Copy planar cells
-         auto & cellSeed = meshBuilder.getCellSeed( setCellsCount++ );
+      const bool planar = planarCache[ i ];
+      if( planar ) { // Copy planar cells
+         auto seed = meshBuilder.getCellSeed( setCellsCount++ );
          const auto verticesCount = cell.template getSubentitiesCount< 0 >();
-         cellSeed.setCornersCount( verticesCount );
          for( LocalIndexType j = 0; j < verticesCount; j++ ) {
-            cellSeed.setCornerId( j, cell.template getSubentityIndex< 0 >( j ) );
+            seed.setCornerId( j, cell.template getSubentityIndex< 0 >( j ) );
          }
       }
       else { // Decompose non-planar cells
@@ -124,7 +147,7 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
 
    FaceMapArray faceMap( inFacesCount ); // Mapping of original face indeces to a group of decomposed face indices
 
-   // Find the number of points and faces in the outMesh and setup faceMap
+   // Count the number of points and faces in the outMesh and setup faceMap
    GlobalIndexType outPointsCount = inPointsCount;
    GlobalIndexType outFacesCount = 0;
    for( GlobalIndexType i = 0; i < inFacesCount; i++ ) {
@@ -155,32 +178,40 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
       meshBuilder.setPoint( setPointsCount, inMesh.getPoint( setPointsCount ) );
    }
 
-   // Set up cell seeds
+   // set cell corner counts
    for( GlobalIndexType i = 0; i < inCellsCount; i++ ) {
       const auto cell = inMesh.template getEntity< 3 >( i );
       const LocalIndexType cellFacesCount = cell.template getSubentitiesCount< 2 >();
 
-      // Find the number of faces in the output cell
-      LocalIndexType cellSeedFacesCount = 0;
+      // Count the number of faces in the cell
+      LocalIndexType cornersCount = 0;
       for( LocalIndexType j = 0; j < cellFacesCount; j++ ) {
          const GlobalIndexType faceIdx = cell.template getSubentityIndex< 2 >( j );
          const auto & faceMapping = faceMap[ faceIdx ];
-         cellSeedFacesCount += faceMapping.second - faceMapping.first;
+         cornersCount += faceMapping.second - faceMapping.first;
       }
 
-      // Set up the cell seed
-      auto & cellSeed = meshBuilder.getCellSeed( i );
-      cellSeed.setCornersCount( cellSeedFacesCount );
-      for( LocalIndexType j = 0, faceSetIdx = 0; j < cellFacesCount; j++ ) {
+      meshBuilder.setCellCornersCount( i, cornersCount );
+   }
+
+   meshBuilder.initializeCellSeeds();
+
+   // Set cell corner ids
+   for( GlobalIndexType i = 0; i < inCellsCount; i++ ) {
+      const auto cell = inMesh.template getEntity< 3 >( i );
+      const LocalIndexType cellFacesCount = cell.template getSubentitiesCount< 2 >();
+
+      for( LocalIndexType j = 0, o = 0; j < cellFacesCount; j++ ) {
          const GlobalIndexType faceIdx = cell.template getSubentityIndex< 2 >( j );
          const auto & faceMapping = faceMap[ faceIdx ];
+         auto cellSeed = meshBuilder.getCellSeed( i );
          for( GlobalIndexType k = faceMapping.first; k < faceMapping.second; k++ ) {
-            cellSeed.setCornerId( faceSetIdx++, k );
+            cellSeed.setCornerId( o++, k );
          }
       }
    }
 
-   // set corners count for face seeds
+   // set face corners count
    GlobalIndexType setFacesCount = 0;
    for( GlobalIndexType i = 0; i < inFacesCount; i++ ) {
       const auto & faceMapping = faceMap[ i ];
@@ -199,13 +230,13 @@ getPlanarMesh( const Mesh< MeshConfig, Devices::Host > & inMesh )
    meshBuilder.initializeFaceSeeds();
 
    // Lambda for creating new points
-   auto createPointFunc = [&] ( const PointType & point ) {
+   auto createPointFunc = [&] ( const PointType& point ) {
       const auto pointIdx = setPointsCount++;
       meshBuilder.setPoint( pointIdx, point );
       return pointIdx;
    };
 
-   // Lambda for setting seed of decomposed triangle
+   // Lambda for setting corner ids of decomposed faces
    setFacesCount = 0;
    auto setDecomposedFaceFunc = [&] ( GlobalIndexType v0, GlobalIndexType v1, GlobalIndexType v2 ) {
       const GlobalIndexType faceId = setFacesCount++;
diff --git a/src/TNL/Meshes/Mesh.h b/src/TNL/Meshes/Mesh.h
index 8b04acbd4f95fbb43757f348f9d0afeef3431289..2513982f39599238dfa75cd756bdeb7e57907401 100644
--- a/src/TNL/Meshes/Mesh.h
+++ b/src/TNL/Meshes/Mesh.h
@@ -51,7 +51,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::FaceSeedMatrixType& faceSeeds,
-                 typename MeshTraitsType::CellSeedArrayType& cellSeeds );
+                 typename MeshTraitsType::CellSeedMatrixType& cellSeeds );
 };
 
 // The mesh cannot be initialized on CUDA GPU, so this specialization is empty.
diff --git a/src/TNL/Meshes/Mesh.hpp b/src/TNL/Meshes/Mesh.hpp
index d23a335775683cdf71aa81df69dc7d036e4fbe64..c928783f4751b9f46c663d316d03fce55830cb28 100644
--- a/src/TNL/Meshes/Mesh.hpp
+++ b/src/TNL/Meshes/Mesh.hpp
@@ -28,7 +28,7 @@ void
 MeshInitializableBase< MeshConfig, Device, MeshType >::
 init( typename MeshTraitsType::PointArrayType& points,
       typename MeshTraitsType::FaceSeedMatrixType& faceSeeds,
-      typename MeshTraitsType::CellSeedArrayType& cellSeeds )
+      typename MeshTraitsType::CellSeedMatrixType& cellSeeds )
 {
    MeshType* mesh = static_cast< MeshType* >( this );
    Initializer< typename MeshType::Config > initializer;
diff --git a/src/TNL/Meshes/MeshBuilder.h b/src/TNL/Meshes/MeshBuilder.h
index 6269169759913c8803a12433835ba63c723716c2..303113a17728dcfa3840275e66ed87728c57c978 100644
--- a/src/TNL/Meshes/MeshBuilder.h
+++ b/src/TNL/Meshes/MeshBuilder.h
@@ -31,8 +31,8 @@ public:
    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 CellSeedType       = typename CellSeedMatrixType::EntitySeedMatrixSeed;
    using FaceSeedMatrixType = typename MeshTraitsType::FaceSeedMatrixType;
    using FaceSeedType       = typename FaceSeedMatrixType::EntitySeedMatrixSeed;
    
@@ -60,7 +60,20 @@ public:
 
    void setCellsCount( const GlobalIndexType& cellsCount )
    {
-      this->cellSeeds.setSize( cellsCount );
+      if( getFacesCount() == 0 ) // faceSeeds aren't used ( cellSeeds store indeces of points )
+         this->cellSeeds.setDimensions( cellsCount, getPointsCount() );
+      else // faceSeeds are used ( cellSeeds store indeces of faces )
+         this->cellSeeds.setDimensions( cellsCount, getFacesCount() );
+   }
+
+   void setCellCornersCount( const GlobalIndexType& cellIndex, const LocalIndexType& cornersCount )
+   {
+      this->cellSeeds.setEntityCornersCount( cellIndex, cornersCount );
+   }
+
+   void initializeCellSeeds()
+   {
+      this->cellSeeds.initializeRows();
    }
 
    GlobalIndexType getPointsCount() const
@@ -75,7 +88,7 @@ public:
 
    GlobalIndexType getCellsCount() const
    {
-      return this->cellSeeds.getSize();
+      return this->cellSeeds.getEntitiesCount();
    }
 
    void setPoint( GlobalIndexType index,
@@ -90,9 +103,9 @@ public:
       return this->faceSeeds.getSeed( index );
    }
 
-   CellSeedType& getCellSeed( GlobalIndexType index )
+   CellSeedType getCellSeed( GlobalIndexType index )
    {
-      return this->cellSeeds[ index ];
+      return this->cellSeeds.getSeed( index );
    }
 
    bool build( MeshType& mesh )
@@ -105,8 +118,6 @@ 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 >;
 
    bool validate() const
@@ -123,11 +134,12 @@ private:
       if( faceSeeds.empty() )
       {
          for( GlobalIndexType i = 0; i < getCellsCount(); i++ ) {
-            const auto& cornerIds = this->cellSeeds[ i ].getCornerIds();
-            for( LocalIndexType j = 0; j < cornerIds.getSize(); j++ ) {
-               assignedPoints[ cornerIds[ j ] ] = true;
-               if( cornerIds[ j ] < 0 || getPointsCount() <= cornerIds[ j ] ) {
-                  std::cerr << "Cell seed " << i << " is referencing unavailable point " << cornerIds[ j ] << std::endl;
+            const auto cellSeed = this->cellSeeds.getSeed( i );
+            for( LocalIndexType j = 0; j < cellSeed.getCornersCount(); j++ ) {
+               const GlobalIndexType cornerId = cellSeed.getCornerId( j );
+               assignedPoints[ cornerId ] = true;
+               if( cornerId < 0 || getPointsCount() <= cornerId ) {
+                  std::cerr << "Cell seed " << i << " is referencing unavailable point " << cornerId << std::endl;
                   return false;
                }
             }
@@ -143,11 +155,12 @@ private:
          for( GlobalIndexType i = 0; i < getFacesCount(); i++ ) {
             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;
+               const GlobalIndexType cornerId = faceSeed.getCornerId( j );
+               if( cornerId < 0 || getPointsCount() <= cornerId ) {
+                  std::cerr << "face seed " << i << " is referencing unavailable point " << cornerId << std::endl;
                   return false;
                }
-               assignedPoints[ faceSeed.getCornerId( j ) ] = true;
+               assignedPoints[ cornerId ] = true;
             }
          }
 
@@ -161,13 +174,14 @@ private:
          assignedFaces.setValue( false );
 
          for( GlobalIndexType i = 0; i < getCellsCount(); i++ ) {
-            const auto& cornerIds = this->cellSeeds[ i ].getCornerIds();
-            for( LocalIndexType j = 0; j < cornerIds.getSize(); j++ ) {
-               if( cornerIds[ j ] < 0 || getFacesCount() <= cornerIds[ j ] ) {
-                  std::cerr << "cell seed " << i << " is referencing unavailable face " << cornerIds[ j ] << std::endl;
+            const auto cellSeed = this->cellSeeds.getSeed( i );
+            for( LocalIndexType j = 0; j < cellSeed.getCornersCount(); j++ ) {
+               const GlobalIndexType cornerId = cellSeed.getCornerId( j );
+               if( cornerId < 0 || getFacesCount() <= cornerId ) {
+                  std::cerr << "cell seed " << i << " is referencing unavailable face " << cornerId << std::endl;
                   return false;
                }
-               assignedFaces[ cornerIds[ j ] ] = true;
+               assignedFaces[ cornerId ] = true;
             }
          }
 
@@ -182,7 +196,7 @@ private:
 
    PointArrayType points;
    FaceSeedMatrixType faceSeeds;
-   CellSeedArrayType cellSeeds;
+   CellSeedMatrixType cellSeeds;
    BoolVector pointsSet;
 };
 
diff --git a/src/TNL/Meshes/MeshDetails/initializer/EntityInitializer.h b/src/TNL/Meshes/MeshDetails/initializer/EntityInitializer.h
index 358c1a18b9c85a3cb38a6e7f74a40becd33d6aa8..3ac007b7273398cc731c3b746af050fb88aee353 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/EntityInitializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/EntityInitializer.h
@@ -50,13 +50,14 @@ class EntityInitializer
                                             DimensionTag< MeshTraits< MeshConfig >::meshDimension > >;
 
    using MeshTraitsType      = MeshTraits< MeshConfig >;
+   using EntityTraitsType    = typename MeshTraitsType::template EntityTraits< EntityTopology::dimension >;
    using GlobalIndexType     = typename MeshTraitsType::GlobalIndexType;
    using LocalIndexType      = typename MeshTraitsType::LocalIndexType;
 
    using SeedType            = EntitySeed< MeshConfig, EntityTopology >;
    using InitializerType     = Initializer< MeshConfig >;
    using NeighborCountsArray = typename MeshTraitsType::NeighborCountsArray;
-   using SeedMatrixType      = EntitySeedMatrix< MeshConfig, EntityTopology >;
+   using SeedMatrixType      = typename EntityTraitsType::SeedMatrixType;
 
 public:
    static void initSubvertexMatrix( NeighborCountsArray& capacities, InitializerType& initializer )
@@ -64,19 +65,19 @@ public:
       initializer.template initSubentityMatrix< EntityTopology::dimension, 0 >( capacities );
    }
 
-   static void initEntity( const GlobalIndexType entityIndex, const SeedType& entitySeed, InitializerType& initializer )
-   {
-      // this is necessary if we want to use existing entities instead of intermediate seeds to create subentity seeds
-      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() );
    }
+
+   static void initEntity( const GlobalIndexType entityIndex, const SeedType& entitySeed, InitializerType& initializer )
+   {
+      // this is necessary if we want to use existing entities instead of intermediate seeds to create subentity seeds
+      for( LocalIndexType i = 0; i < entitySeed.getCornerIds().getSize(); i++ )
+         initializer.template setSubentityIndex< EntityTopology::dimension, 0 >( entityIndex, i, entitySeed.getCornerIds()[ i ] );
+   }
 };
 
 template< typename MeshConfig,
@@ -87,13 +88,16 @@ class EntityInitializer< MeshConfig, EntityTopology, false >
                                     DimensionTag< MeshTraits< MeshConfig >::meshDimension > >
 {
    using MeshTraitsType   = MeshTraits< MeshConfig >;
+   using EntityTraitsType    = typename MeshTraitsType::template EntityTraits< EntityTopology::dimension >;
    using GlobalIndexType  = typename MeshTraitsType::GlobalIndexType;
 
    using SeedType         = EntitySeed< MeshConfig, EntityTopology >;
    using InitializerType  = Initializer< MeshConfig >;
    using NeighborCountsArray = typename MeshTraitsType::NeighborCountsArray;
+   using SeedMatrixType      = typename EntityTraitsType::SeedMatrixType;
 public:
    static void initSubvertexMatrix( const NeighborCountsArray& capacities, InitializerType& initializer ) {}
+   static void initSubvertexMatrix( SeedMatrixType& seeds, InitializerType& initializer ) {}
    static void initEntity( const GlobalIndexType entityIndex, const SeedType& entitySeed, InitializerType& initializer ) {}
 };
 
@@ -238,31 +242,25 @@ public:
       const GlobalIndexType subentitiesCount = mesh.template getEntitiesCount< SubdimensionTag::value >();
       const GlobalIndexType superentitiesCount = mesh.template getEntitiesCount< SuperdimensionTag::value >();
 
-      auto& cellSeeds = meshInitializer.getCellSeeds();
-
-      NeighborCountsArray capacities( cellSeeds.getSize() );
-
-      for( GlobalIndexType superentityIndex = 0; superentityIndex < capacities.getSize(); superentityIndex++ )
-         capacities[ superentityIndex ] = cellSeeds[ superentityIndex ].getCornersCount();
-
-      meshInitializer.template initSubentityMatrix< SuperdimensionTag::value, SubdimensionTag::value >( capacities, subentitiesCount );
-
       // counter for superentities of each subentity
       auto& superentitiesCounts = meshInitializer.template getSuperentitiesCountsArray< SubdimensionTag::value, SuperdimensionTag::value >();
       superentitiesCounts.setSize( subentitiesCount );
       superentitiesCounts.setValue( 0 );
 
+      auto& cellSeeds = meshInitializer.getCellSeeds();
       for( GlobalIndexType superentityIndex = 0; superentityIndex < superentitiesCount; superentityIndex++ )
       {
-         auto& cellSeed = cellSeeds[ superentityIndex ];
+         const auto cellSeed = cellSeeds.getSeed( superentityIndex );
          for( LocalIndexType i = 0; i < cellSeed.getCornersCount(); i++ )
          {
-            const GlobalIndexType subentityIndex = cellSeed.getCornerIds()[ i ];
-            meshInitializer.template setSubentityIndex< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex, i, subentityIndex );
+            const GlobalIndexType subentityIndex = cellSeed.getCornerId( i );
             superentitiesCounts[ subentityIndex ]++;
          }
       }
-      cellSeeds.reset();
+
+      auto& subvertexMatrix = meshInitializer.template getSubentitiesMatrix< SuperdimensionTag::value, SubdimensionTag::value >();
+      subvertexMatrix = std::move( cellSeeds.getMatrix() );
+      meshInitializer.template initSubentitiesCounts< SuperdimensionTag::value, SubdimensionTag::value >( cellSeeds.getEntityCornerCounts() );
 
       // allocate superentities storage
       SuperentityMatrixType& matrix = meshInitializer.template getSuperentitiesMatrix< SubdimensionTag::value, SuperdimensionTag::value >();
@@ -395,30 +393,10 @@ public:
    static void initSuperentities( InitializerType& meshInitializer, MeshType& mesh )
    {
       //std::cout << "   Initiating superentities with dimension " << SuperdimensionTag::value << " for subentities with dimension " << SubdimensionTag::value << " ... " << std::endl;
-
-      const GlobalIndexType subentitiesCount = mesh.template getEntitiesCount< SubdimensionTag::value >();
-      const GlobalIndexType superentitiesCount = mesh.template getEntitiesCount< SuperdimensionTag::value >();
-
       auto& cellSeeds = meshInitializer.getCellSeeds();
-
-      NeighborCountsArray capacities( cellSeeds.getSize() );
-
-      for( GlobalIndexType superentityIndex = 0; superentityIndex < capacities.getSize(); superentityIndex++ )
-         capacities[ superentityIndex ] = cellSeeds[ superentityIndex ].getCornersCount();
-
-      meshInitializer.template initSubentityMatrix< SuperdimensionTag::value, SubdimensionTag::value >( capacities, subentitiesCount );
-
-      for( GlobalIndexType superentityIndex = 0; superentityIndex < superentitiesCount; superentityIndex++ )
-      {
-         auto& cellSeed = cellSeeds[ superentityIndex ];
-         for( LocalIndexType i = 0; i < cellSeed.getCornersCount(); i++ )
-         {
-            const GlobalIndexType subentityIndex = cellSeed.getCornerIds()[ i ];
-            meshInitializer.template setSubentityIndex< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex, i, subentityIndex );
-         }
-      }
-      cellSeeds.reset();
-
+      auto& subvertexMatrix = meshInitializer.template getSubentitiesMatrix< SuperdimensionTag::value, SubdimensionTag::value >();
+      subvertexMatrix = std::move( cellSeeds.getMatrix() );
+      meshInitializer.template initSubentitiesCounts< SuperdimensionTag::value, SubdimensionTag::value >( cellSeeds.getEntityCornerCounts() );
       BaseType::initSuperentities( meshInitializer, mesh );
    }
 };
diff --git a/src/TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h b/src/TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h
index 3e9781d2b33d9eda5e42bf12c0042f666065756a..0d9460ea9c435a11fc30e4a30d61422be224e983 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/EntitySeedMatrix.h
@@ -28,8 +28,6 @@ class EntitySeedMatrix< MeshConfig, EntityTopology, false >
       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;
@@ -41,7 +39,7 @@ class EntitySeedMatrix< MeshConfig, EntityTopology, false >
 
             static constexpr LocalIndexType getCornersCount()
             {
-               return cornersCount;
+               return SubentityTraitsType::count;
             }
 
             void setCornerId( const LocalIndexType& cornerIndex, const GlobalIndexType& pointIndex )
@@ -72,7 +70,7 @@ class EntitySeedMatrix< MeshConfig, EntityTopology, false >
 
             static constexpr LocalIndexType getCornersCount()
             {
-               return cornersCount;
+               return SubentityTraitsType::count;
             }
 
             GlobalIndexType getCornerId( const LocalIndexType& cornerIndex ) const
@@ -89,7 +87,7 @@ class EntitySeedMatrix< MeshConfig, EntityTopology, false >
          matrix.setDimensions( entitiesCount, pointsCount );
 
          NeighborCountsArray capacities( entitiesCount );
-         capacities.setValue( cornersCount );
+         capacities.setValue( SubentityTraitsType::count );
          matrix.setRowCapacities( capacities );
       }
 
@@ -106,24 +104,137 @@ class EntitySeedMatrix< MeshConfig, EntityTopology, false >
          matrix.reset();
       }
 
-      void setSeedIndex( const GlobalIndexType& entityIndex, const LocalIndexType& localIndex, const GlobalIndexType& globalIndex )
+      GlobalIndexType getEntitiesCount() const
       {
-         matrix.getRow( entityIndex ).setElement( localIndex, globalIndex, true );
+         return matrix.getRows();
       }
 
-      GlobalIndexType getEntitiesCount() const
+      SubentityMatrixType& getMatrix()
       {
-         return matrix.getRows();
+         return matrix;
+      }
+
+      const SubentityMatrixType& getMatrix() const
+      {
+         return matrix;
+      }
+
+      NeighborCountsArray getEntityCornerCounts() const
+      {
+         NeighborCountsArray counts( getEntitiesCount() );
+         counts.setValue( SubentityTraitsType::count );
+         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 >
+class EntitySeedMatrix< MeshConfig, Topologies::Vertex, false >
+{
+   using MeshTraitsType = MeshTraits< MeshConfig, Devices::Host >;
+
+   public:
+      using GlobalIndexType = typename MeshTraitsType::GlobalIndexType;
+      using LocalIndexType  = typename MeshTraitsType::LocalIndexType;
+      using SubentityMatrixType = typename MeshTraitsType::template SubentityMatrixType< 0 >;
+      using NeighborCountsArray = typename MeshTraitsType::NeighborCountsArray;
+
+      class EntitySeedMatrixSeed
+      {
+         using RowView = typename SubentityMatrixType::RowView;
+
+         public:
+            EntitySeedMatrixSeed( const RowView& matrixRow )
+            : row( matrixRow )
+            {}
+
+            static constexpr LocalIndexType getCornersCount()
+            {
+               return 1;
+            }
+
+            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 1;
+            }
+
+            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( 1 );
+         matrix.setRowCapacities( capacities );
       }
 
-      constexpr LocalIndexType getEntityCornersCount( const GlobalIndexType& entityIndex ) const
+      // 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()
       {
-         return cornersCount;
+         matrix.reset();
       }
 
-      GlobalIndexType getSeedIndex( const GlobalIndexType& entityIndex, const LocalIndexType& localIndex ) const
+      GlobalIndexType getEntitiesCount() const
       {
-         return matrix.getRow( entityIndex ).getColumnIndex( localIndex );
+         return matrix.getRows();
       }
 
       SubentityMatrixType& getMatrix()
@@ -139,7 +250,7 @@ class EntitySeedMatrix< MeshConfig, EntityTopology, false >
       NeighborCountsArray getEntityCornerCounts() const
       {
          NeighborCountsArray counts( getEntitiesCount() );
-         counts.setValue( cornersCount );
+         counts.setValue( 1 );
          return counts;
       }
 
@@ -254,26 +365,11 @@ class EntitySeedMatrix< MeshConfig, EntityTopology, true >
          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;
diff --git a/src/TNL/Meshes/MeshDetails/initializer/Initializer.h b/src/TNL/Meshes/MeshDetails/initializer/Initializer.h
index ef840d2b8159940246077750ee96899e3e3d3f29..aefbe2f72b341ab1d6e86d55daa0730ecc6075dd 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/Initializer.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/Initializer.h
@@ -77,7 +77,7 @@ class Initializer
       using DimensionTag      = Meshes::DimensionTag< MeshTraitsType::meshDimension >;
       using BaseType          = InitializerLayer< MeshConfig, DimensionTag >;
       using PointArrayType    = typename MeshTraitsType::PointArrayType;
-      using CellSeedArrayType = typename MeshTraitsType::CellSeedArrayType;
+      using CellSeedMatrixType = typename MeshTraitsType::CellSeedMatrixType;
       using FaceSeedMatrixType = typename MeshTraitsType::FaceSeedMatrixType;
       using GlobalIndexType   = typename MeshTraitsType::GlobalIndexType;
       using LocalIndexType    = typename MeshTraitsType::LocalIndexType;
@@ -89,7 +89,7 @@ class Initializer
       // The points and cellSeeds arrays will be reset when not needed to save memory.
       void createMesh( PointArrayType& points,
                        FaceSeedMatrixType& faceSeeds,
-                       CellSeedArrayType& cellSeeds,
+                       CellSeedMatrixType& cellSeeds,
                        MeshType& mesh )
       {
          // copy points
@@ -178,12 +178,12 @@ class Initializer
          return mesh->template getSuperentitiesMatrix< Dimension, Superdimension >();
       }
 
-      CellSeedArrayType& getCellSeeds()
+      CellSeedMatrixType& getCellSeeds()
       {
          return *(this->cellSeeds);
       }
    protected:
-      CellSeedArrayType* cellSeeds = nullptr;
+      CellSeedMatrixType* cellSeeds = nullptr;
 };
 
 /****
@@ -207,35 +207,24 @@ protected:
 
    using InitializerType       = Initializer< MeshConfig >;
    using EntityInitializerType = EntityInitializer< MeshConfig, EntityTopology >;
-   using CellSeedArrayType     = typename MeshTraitsType::CellSeedArrayType;
+   using CellSeedMatrixType     = typename MeshTraitsType::CellSeedMatrixType;
    using FaceSeedMatrixType    = typename MeshTraitsType::FaceSeedMatrixType;
    using NeighborCountsArray   = typename MeshTraitsType::NeighborCountsArray;
 
    public:
 
-      void initEntities( InitializerType& initializer, CellSeedArrayType& cellSeeds, MeshType& mesh )
+      void initEntities( InitializerType& initializer, CellSeedMatrixType& cellSeeds, MeshType& mesh )
       {
          //std::cout << " Initiating entities with dimension " << DimensionTag::value << " ... " << std::endl;
-         initializer.template setEntitiesCount< DimensionTag::value >( cellSeeds.getSize() );
-
-         NeighborCountsArray capacities( cellSeeds.getSize() );
-
-         for( GlobalIndexType i = 0; i < capacities.getSize(); i++ )
-            capacities[ i ] = cellSeeds[ i ].getCornersCount();
-
-         EntityInitializerType::initSubvertexMatrix( capacities, initializer );
-
-         for( GlobalIndexType i = 0; i < cellSeeds.getSize(); i++ )
-            EntityInitializerType::initEntity( i, cellSeeds[ i ], initializer );
-         cellSeeds.reset();
-
+         initializer.template setEntitiesCount< DimensionTag::value >( cellSeeds.getEntitiesCount() );
+         EntityInitializerType::initSubvertexMatrix( cellSeeds, initializer );
          BaseType::initEntities( initializer, 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() );
+         initializer.template setEntitiesCount< DimensionTag::value >( initializer.getCellSeeds().getEntitiesCount() );
          BaseType::initEntities( initializer, faceSeeds, mesh );
       }
       
@@ -265,8 +254,7 @@ protected:
    using EntityInitializerType = EntityInitializer< MeshConfig, EntityTopology >;
    using SeedType              = EntitySeed< MeshConfig, EntityTopology >;
    using SeedIndexedSet        = typename MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::SeedIndexedSetType;
-   using CellSeedArrayType     = typename MeshTraitsType::CellSeedArrayType;
-   using FaceSeedMatrixType    = typename MeshTraitsType::FaceSeedMatrixType;
+   using SeedMatrixType        = typename EntityTraitsType::SeedMatrixType;
    using NeighborCountsArray   = typename MeshTraitsType::NeighborCountsArray;
    
    public:
@@ -321,19 +309,13 @@ protected:
          BaseType::initEntities( initializer, mesh );
       }
 
-      void initEntities( InitializerType& initializer, FaceSeedMatrixType& faceSeeds, MeshType& mesh )
+      void initEntities( InitializerType& initializer, SeedMatrixType& seeds, MeshType& mesh )
       {
          //std::cout << " Initiating entities with dimension " << DimensionTag::value << " ... " << std::endl;
-
-         initializer.template setEntitiesCount< DimensionTag::value >( faceSeeds.getEntitiesCount() );
-
-         EntityInitializerType::initSubvertexMatrix( faceSeeds, initializer );
-
-         // initialize links between the entities and all superentities
-         EntityInitializerType::initSuperentities( initializer, mesh );
-
-         // continue with the next dimension
-         BaseType::initEntities( initializer, mesh );
+         initializer.template setEntitiesCount< DimensionTag::value >( seeds.getEntitiesCount() );
+         EntityInitializerType::initSubvertexMatrix( seeds, initializer );
+         EntityInitializerType::initSuperentities( initializer, mesh ); // initialize links between the entities and all superentities
+         BaseType::initEntities( initializer, mesh ); // continue with the next dimension
       }
 
    private:
@@ -358,7 +340,7 @@ class InitializerLayer< MeshConfig, DimensionTag< 0 > >
    using InitializerType       = Initializer< MeshConfig >;
    using EntityInitializerType = EntityInitializer< MeshConfig, EntityTopology >;
    using SeedType              = EntitySeed< MeshConfig, EntityTopology >;
-   using FaceSeedMatrixType    = typename MeshTraitsType::FaceSeedMatrixType;
+   using SeedMatrixType        = typename EntityTraitsType::SeedMatrixType;
 
    public:
 
@@ -374,7 +356,7 @@ class InitializerLayer< MeshConfig, DimensionTag< 0 > >
       }
 
       // This overload is only here for compatibility with Polyhedrons, it is never called
-      void initEntities( InitializerType& initializer, FaceSeedMatrixType& faceSeeds, MeshType& mesh )
+      void initEntities( InitializerType& initializer, SeedMatrixType& faceSeeds, MeshType& mesh )
       {
       }
 };
diff --git a/src/TNL/Meshes/MeshDetails/initializer/SubentitySeedsCreator.h b/src/TNL/Meshes/MeshDetails/initializer/SubentitySeedsCreator.h
index 641e96110d477f95475bb6630042f7311a5be4f6..b0c531ba97e3e19536c3729182b0f029381186d5 100644
--- a/src/TNL/Meshes/MeshDetails/initializer/SubentitySeedsCreator.h
+++ b/src/TNL/Meshes/MeshDetails/initializer/SubentitySeedsCreator.h
@@ -267,15 +267,15 @@ public:
    static SubentitySeedArray create( InitializerType& initializer, MeshType& mesh, const GlobalIndexType entityIndex )
    {
       const auto& cellSeeds = initializer.getCellSeeds();
-      const auto& faces = cellSeeds[ entityIndex ].getCornerIds();
+      const auto faces = cellSeeds.getSeed( entityIndex );
 
       SubentitySeedArray seeds;
-      seeds.setSize( faces.getSize() );
+      seeds.setSize( faces.getCornersCount() );
 
       for( LocalIndexType i = 0; i < seeds.getSize(); i++ )
       {
          SubentitySeed& seed = seeds[ i ];
-         GlobalIndexType faceIdx = faces[ i ];
+         GlobalIndexType faceIdx = faces.getCornerId( i );
          const auto& subvertices = mesh.template getSubentitiesMatrix< 2, 0 >().getRow( faceIdx );
          const LocalIndexType subverticesCount = mesh.template getSubentitiesCount< 2, 0 >( faceIdx );
          seed.setCornersCount( subverticesCount );
@@ -292,11 +292,11 @@ public:
    static void iterate( InitializerType& initializer, MeshType& mesh, const GlobalIndexType entityIndex, FunctorType&& functor )
    {
       const auto& cellSeeds = initializer.getCellSeeds();
-      const auto& faces = cellSeeds[ entityIndex ].getCornerIds();
+      const auto faces = cellSeeds.getSeed( entityIndex );
 
-      for( LocalIndexType i = 0; i < faces.getSize(); i++ )
+      for( LocalIndexType i = 0; i < faces.getCornersCount(); i++ )
       {
-         GlobalIndexType faceIdx = faces[ i ];
+         GlobalIndexType faceIdx = faces.getCornerId( i );
          const auto& subvertices = mesh.template getSubentitiesMatrix< 2, 0 >().getRow( faceIdx );
          const LocalIndexType subverticesCount = mesh.template getSubentitiesCount< 2, 0 >( faceIdx );
          SubentitySeed seed;
@@ -310,8 +310,8 @@ public:
 
    static LocalIndexType getSubentitiesCount( InitializerType& initializer, MeshType& mesh, const GlobalIndexType entityIndex )
    {
-      auto& cellSeeds = initializer.getCellSeeds();
-      return cellSeeds[ entityIndex ].getCornersCount();
+      const auto& cellSeeds = initializer.getCellSeeds();
+      return cellSeeds.getSeed( entityIndex ).getCornersCount();
    }
 };
 
diff --git a/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h b/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
index f2c4c8d588a2db665b3601a34b7c31a7dbba1569..cc7fbe4f2e42a70083402e3ae4dad5233c96833c 100644
--- a/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
+++ b/src/TNL/Meshes/MeshDetails/traits/MeshEntityTraits.h
@@ -51,6 +51,7 @@ public:
    
    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 >;
+   using SeedMatrixType                = EntitySeedMatrix< MeshConfig, EntityTopology >;
 
    // container for storing the subentity indices
    using SubentityMatrixType = Matrices::SparseMatrix< bool, Device, GlobalIndexType, Matrices::GeneralMatrix, EllpackSegments >;
@@ -78,6 +79,7 @@ public:
    
    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 >;
+   using SeedMatrixType                = EntitySeedMatrix< MeshConfig, EntityTopology >;
 
    // container for storing the subentity indices
    using SubentityMatrixType = Matrices::SparseMatrix< bool, Device, GlobalIndexType, Matrices::GeneralMatrix, SlicedEllpackSegments >;
diff --git a/src/TNL/Meshes/Readers/MeshReader.h b/src/TNL/Meshes/Readers/MeshReader.h
index ee23cb35b106ef7d2cc6ddf560772b36ffdcb4f4..c52f65d4c2eb8ae14a87a5912be68fee73c20942 100644
--- a/src/TNL/Meshes/Readers/MeshReader.h
+++ b/src/TNL/Meshes/Readers/MeshReader.h
@@ -208,7 +208,7 @@ public:
 
                offsetStart = 0;
                for( std::size_t i = 0; i < NumberOfFaces; i++ ) {
-                  auto seed = meshBuilder.getFaceSeed( i );
+                  FaceSeedType 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 ] );
@@ -223,11 +223,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)> >( cellOffsetsArray );
+
                std::size_t offsetStart = 0;
                for( std::size_t i = 0; i < NumberOfCells; i++ ) {
-                  CellSeedType& seed = meshBuilder.getCellSeed( i );
                   const std::size_t offsetEnd = offsets[ i ];
-                  seed.setCornersCount( offsetEnd - offsetStart );
+                  meshBuilder.setCellCornersCount( i, offsetEnd - offsetStart );
+                  offsetStart = offsetEnd;
+               }
+               meshBuilder.initializeCellSeeds();
+
+               offsetStart = 0;
+               for( std::size_t i = 0; i < NumberOfCells; i++ ) {
+                  CellSeedType seed = meshBuilder.getCellSeed( 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 a87932b9c708d425eef42f2e2ae8e68e12a6b6bd..df02b42a5cf8ea1f7529ba9ebcc89ce90bf14542 100644
--- a/src/UnitTests/Meshes/MeshGeometryTest.h
+++ b/src/UnitTests/Meshes/MeshGeometryTest.h
@@ -90,8 +90,9 @@ TEST( MeshGeometryTest, Polygon2DAreaTest )
    meshBuilder.setPoint( 4, point4 );
 
    meshBuilder.setCellsCount( 1 );
+   meshBuilder.setCellCornersCount( 0, 5 );
+   meshBuilder.initializeCellSeeds();
 
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 );
@@ -139,7 +140,9 @@ TEST( MeshGeometryTest, Polygon3DAreaTest )
    meshBuilder.setPoint(  4, point4  );
 
    meshBuilder.setCellsCount( 1 );
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 5 );
+   meshBuilder.setCellCornersCount( 0, 5 );
+   meshBuilder.initializeCellSeeds();
+
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 );
@@ -319,7 +322,9 @@ TEST( MeshGeometryTest, PolyhedronAreaTest )
    meshBuilder.getFaceSeed( 8 ).setCornerId( 2, 8 );
 
    meshBuilder.setCellsCount( 1 );
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 9 );
+   meshBuilder.setCellCornersCount( 0, 9 );
+   meshBuilder.initializeCellSeeds();
+
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 );
@@ -386,9 +391,15 @@ TEST( MeshGeometryTest, Polygon3DIsPlanarTest )
    meshBuilder.setPoint(  9, point4_ );
 
    meshBuilder.setCellsCount( 6 );
+   meshBuilder.setCellCornersCount( 0, 5 );
+   meshBuilder.setCellCornersCount( 1, 5 );
+   meshBuilder.setCellCornersCount( 2, 5 );
+   meshBuilder.setCellCornersCount( 3, 5 );
+   meshBuilder.setCellCornersCount( 4, 5 );
+   meshBuilder.setCellCornersCount( 5, 5 );
+   meshBuilder.initializeCellSeeds();
 
    // Planar cell with non-deviated points
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 );
@@ -396,7 +407,6 @@ TEST( MeshGeometryTest, Polygon3DIsPlanarTest )
    meshBuilder.getCellSeed( 0 ).setCornerId( 4, 4 );
 
    // Non-Planar cell with 0th point deviated
-   meshBuilder.getCellSeed( 1 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 0, 5 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2, 2 );
@@ -404,7 +414,6 @@ TEST( MeshGeometryTest, Polygon3DIsPlanarTest )
    meshBuilder.getCellSeed( 1 ).setCornerId( 4, 4 );
 
    // Non-Planar cell with 1th point deviated
-   meshBuilder.getCellSeed( 2 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 1, 6 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 2, 2 );
@@ -412,7 +421,6 @@ TEST( MeshGeometryTest, Polygon3DIsPlanarTest )
    meshBuilder.getCellSeed( 2 ).setCornerId( 4, 4 );
 
    // Non-Planar cell with 2th point deviated
-   meshBuilder.getCellSeed( 3 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 2, 7 );
@@ -420,7 +428,6 @@ TEST( MeshGeometryTest, Polygon3DIsPlanarTest )
    meshBuilder.getCellSeed( 3 ).setCornerId( 4, 4 );
 
    // Non-Planar cell with 3th point deviated
-   meshBuilder.getCellSeed( 4 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 2, 2 );
@@ -428,7 +435,6 @@ TEST( MeshGeometryTest, Polygon3DIsPlanarTest )
    meshBuilder.getCellSeed( 4 ).setCornerId( 4, 4 );
 
    // Non-Planar cell with 4th point deviated
-   meshBuilder.getCellSeed( 5 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 2, 2 );
@@ -486,9 +492,16 @@ TEST( MeshGeometryTest, PolygonDecompositionTest )
     */
 
    meshBuilder.setCellsCount( 7 );
+   meshBuilder.setCellCornersCount( 0, 6 );
+   meshBuilder.setCellCornersCount( 1, 5 );
+   meshBuilder.setCellCornersCount( 2, 4 );
+   meshBuilder.setCellCornersCount( 3, 4 );
+   meshBuilder.setCellCornersCount( 4, 5 );
+   meshBuilder.setCellCornersCount( 5, 5 );
+   meshBuilder.setCellCornersCount( 6, 5 );
+   meshBuilder.initializeCellSeeds();
 
    //   1     0     3     2     4     5
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 6 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 0,  1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1,  0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2,  3 );
@@ -497,7 +510,6 @@ TEST( MeshGeometryTest, PolygonDecompositionTest )
    meshBuilder.getCellSeed( 0 ).setCornerId( 5,  5 );
 
    //   8     7     0     1     6
-   meshBuilder.getCellSeed( 1 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 0,  8 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1,  7 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2,  0 );
@@ -505,21 +517,18 @@ TEST( MeshGeometryTest, PolygonDecompositionTest )
    meshBuilder.getCellSeed( 1 ).setCornerId( 4,  6 );
 
    //   9     3     0     7
-   meshBuilder.getCellSeed( 2 ).setCornersCount( 4 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 0,  9 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 1,  3 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 2,  0 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 3,  7 );
 
    //   6     1     5    10
-   meshBuilder.getCellSeed( 3 ).setCornersCount( 4 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 0,  6 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 1,  1 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 2,  5 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 3, 10 );
 
    //  12    11     2     3     9
-   meshBuilder.getCellSeed( 4 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 0, 12 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 1, 11 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 2,  2 );
@@ -527,7 +536,6 @@ TEST( MeshGeometryTest, PolygonDecompositionTest )
    meshBuilder.getCellSeed( 4 ).setCornerId( 4,  9 );
 
    //  13     4     2    11    14
-   meshBuilder.getCellSeed( 5 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 0, 13 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 1,  4 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 2,  2 );
@@ -535,7 +543,6 @@ TEST( MeshGeometryTest, PolygonDecompositionTest )
    meshBuilder.getCellSeed( 5 ).setCornerId( 4, 14 );
 
    //  10     5     4    13    15
-   meshBuilder.getCellSeed( 6 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 6 ).setCornerId( 0, 10 );
    meshBuilder.getCellSeed( 6 ).setCornerId( 1,  5 );
    meshBuilder.getCellSeed( 6 ).setCornerId( 2,  4 );
@@ -786,9 +793,11 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
     */
 
    meshBuilder.setCellsCount( 2 );
+   meshBuilder.setCellCornersCount( 0, 9 );
+   meshBuilder.setCellCornersCount( 1, 8 );
+   meshBuilder.initializeCellSeeds();
 
    //   0     1     2     3     4     5      6     7     8
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 9 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 );
@@ -800,7 +809,6 @@ TEST( MeshGeometryTest, PolyhedronDecompositionTest )
    meshBuilder.getCellSeed( 0 ).setCornerId( 8, 8 );
 
    //   9    10    11    12    13     5     14    15
-   meshBuilder.getCellSeed( 1 ).setCornersCount( 8 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 0, 9 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1, 10 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2, 11 );
@@ -887,15 +895,16 @@ TEST( MeshGeometryTest, Polygon3DGetPlanarMeshTest )
    meshBuilder.setPoint(  5, point5  );
 
    meshBuilder.setCellsCount( 2 );
+   meshBuilder.setCellCornersCount( 0, 4 );
+   meshBuilder.setCellCornersCount( 1, 4 );
+   meshBuilder.initializeCellSeeds();
 
    // Planar cell
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 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 );
 
-   meshBuilder.getCellSeed( 1 ).setCornersCount( 4 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 0, 1 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1, 4 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2, 5 );
@@ -1145,9 +1154,11 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
     */
 
    meshBuilder.setCellsCount( 2 );
+   meshBuilder.setCellCornersCount( 0, 9 );
+   meshBuilder.setCellCornersCount( 1, 8 );
+   meshBuilder.initializeCellSeeds();
 
    //   0     1     2     3     4     5      6     7     8
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 9 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 );
@@ -1159,7 +1170,6 @@ TEST( MeshGeometryTest, PolyhedronGetPlanarMeshTest )
    meshBuilder.getCellSeed( 0 ).setCornerId( 8, 8 );
 
    //   9    10    11    12    13     5     14    15
-   meshBuilder.getCellSeed( 1 ).setCornersCount( 8 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 0, 9 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1, 10 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2, 11 );
diff --git a/src/UnitTests/Meshes/MeshTest.h b/src/UnitTests/Meshes/MeshTest.h
index 4ba992bf089798abefb60d5cdc765e09f7499343..96b2c3d6962aeb5fe110aff41c605d9ee0630e48 100644
--- a/src/UnitTests/Meshes/MeshTest.h
+++ b/src/UnitTests/Meshes/MeshTest.h
@@ -1067,14 +1067,15 @@ TEST( MeshTest, TwoPolygonsTest )
    meshBuilder.setPoint( 4, point4 );
 
    meshBuilder.setCellsCount( 2 );
+   meshBuilder.setCellCornersCount( 0, 4 );
+   meshBuilder.setCellCornersCount( 1, 3 );
+   meshBuilder.initializeCellSeeds();
 
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 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 );
 
-   meshBuilder.getCellSeed( 1 ).setCornersCount( 3 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 0, 3 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1, 2 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2, 4 );
@@ -1244,8 +1245,18 @@ TEST( MeshTest, SevenPolygonsTest )
 
    meshBuilder.setCellsCount( 7 );
 
+   meshBuilder.setCellsCount( 7 );
+   meshBuilder.setCellCornersCount( 0, 6 );
+   meshBuilder.setCellCornersCount( 1, 5 );
+   meshBuilder.setCellCornersCount( 2, 4 );
+   meshBuilder.setCellCornersCount( 3, 4 );
+   meshBuilder.setCellCornersCount( 4, 5 );
+   meshBuilder.setCellCornersCount( 5, 5 );
+   meshBuilder.setCellCornersCount( 6, 5 );
+   meshBuilder.initializeCellSeeds();
+
+
    //   1     0     3     2     4     5
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 6 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 0,  1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1,  0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2,  3 );
@@ -1254,7 +1265,6 @@ TEST( MeshTest, SevenPolygonsTest )
    meshBuilder.getCellSeed( 0 ).setCornerId( 5,  5 );
 
    //   8     7     0     1     6
-   meshBuilder.getCellSeed( 1 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 0,  8 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1,  7 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2,  0 );
@@ -1262,21 +1272,18 @@ TEST( MeshTest, SevenPolygonsTest )
    meshBuilder.getCellSeed( 1 ).setCornerId( 4,  6 );
 
    //   9     3     0     7
-   meshBuilder.getCellSeed( 2 ).setCornersCount( 4 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 0,  9 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 1,  3 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 2,  0 );
    meshBuilder.getCellSeed( 2 ).setCornerId( 3,  7 );
 
    //   6     1     5    10
-   meshBuilder.getCellSeed( 3 ).setCornersCount( 4 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 0,  6 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 1,  1 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 2,  5 );
    meshBuilder.getCellSeed( 3 ).setCornerId( 3, 10 );
 
    //  12    11     2     3     9
-   meshBuilder.getCellSeed( 4 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 0, 12 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 1, 11 );
    meshBuilder.getCellSeed( 4 ).setCornerId( 2,  2 );
@@ -1284,7 +1291,6 @@ TEST( MeshTest, SevenPolygonsTest )
    meshBuilder.getCellSeed( 4 ).setCornerId( 4,  9 );
 
    //  13     4     2    11    14
-   meshBuilder.getCellSeed( 5 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 0, 13 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 1,  4 );
    meshBuilder.getCellSeed( 5 ).setCornerId( 2,  2 );
@@ -1292,7 +1298,6 @@ TEST( MeshTest, SevenPolygonsTest )
    meshBuilder.getCellSeed( 5 ).setCornerId( 4, 14 );
 
    //  10     5     4    13    15
-   meshBuilder.getCellSeed( 6 ).setCornersCount( 5 );
    meshBuilder.getCellSeed( 6 ).setCornerId( 0, 10 );
    meshBuilder.getCellSeed( 6 ).setCornerId( 1,  5 );
    meshBuilder.getCellSeed( 6 ).setCornerId( 2,  4 );
@@ -2775,9 +2780,11 @@ TEST( MeshTest, TwoPolyhedronsTest )
     */
 
    meshBuilder.setCellsCount( 2 );
+   meshBuilder.setCellCornersCount( 0, 9 );
+   meshBuilder.setCellCornersCount( 1, 8 );
+   meshBuilder.initializeCellSeeds();
 
    //   0     1     2     3     4     5      6     7     8
-   meshBuilder.getCellSeed( 0 ).setCornersCount( 9 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 0, 0 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 1, 1 );
    meshBuilder.getCellSeed( 0 ).setCornerId( 2, 2 );
@@ -2789,7 +2796,6 @@ TEST( MeshTest, TwoPolyhedronsTest )
    meshBuilder.getCellSeed( 0 ).setCornerId( 8, 8 );
 
    //   9    10    11    12    13     5     14    15
-   meshBuilder.getCellSeed( 1 ).setCornersCount( 8 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 0, 9 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 1, 10 );
    meshBuilder.getCellSeed( 1 ).setCornerId( 2, 11 );