From 2e07f3a57a07bad32454ff628f69336ebef8b977 Mon Sep 17 00:00:00 2001
From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch>
Date: Wed, 15 May 2024 02:35:24 +0200
Subject: [PATCH] Port other missing shapes to the new DB schema

---
 GeoModelExamples/HelloToy/CMakeLists.txt      |   2 +-
 ...ep1_create_store_geo_and_publish_nodes.cpp |  29 +
 .../step2_read_geo_and_published_nodes.cpp    |  38 +-
 GeoModelIO/GeoModelDBManager/CMakeLists.txt   |   2 +-
 .../GeoModelDBManager/GMDBManager.h           |  11 +-
 .../GeoModelDBManager/src/GMDBManager.cpp     | 103 +-
 .../GeoModelRead/GeoModelRead/ReadGeoModel.h  |  43 +-
 .../GeoModelRead/src/BuildGeoShapes.cpp       |   1 +
 GeoModelIO/GeoModelRead/src/BuildGeoShapes.h  |   2 +-
 .../GeoModelRead/src/BuildGeoShapes_Cons.cpp  |  10 +-
 .../GeoModelRead/src/BuildGeoShapes_Cons.h    |   2 +-
 .../GeoModelRead/src/BuildGeoShapes_Para.cpp  |   8 +-
 .../GeoModelRead/src/BuildGeoShapes_Pgon.cpp  |  10 +-
 .../src/BuildGeoShapes_SimplePolygonBrep.cpp  |  81 ++
 .../src/BuildGeoShapes_SimplePolygonBrep.h    |  30 +
 .../GeoModelRead/src/BuildGeoShapes_Trap.cpp  |  44 +
 .../GeoModelRead/src/BuildGeoShapes_Trap.h    |  29 +
 .../GeoModelRead/src/BuildGeoShapes_Trd.cpp   |  37 +
 .../GeoModelRead/src/BuildGeoShapes_Trd.h     |  29 +
 .../GeoModelRead/src/BuildGeoShapes_Tube.cpp  |   2 +-
 .../GeoModelRead/src/BuildGeoShapes_Tube.h    |   2 +-
 .../GeoModelRead/src/BuildGeoShapes_Tubs.cpp  |  36 +
 .../GeoModelRead/src/BuildGeoShapes_Tubs.h    |  28 +
 .../src/BuildGeoShapes_TwistedTrap.cpp        |  46 +
 .../src/BuildGeoShapes_TwistedTrap.h          |  28 +
 GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp  | 883 +++++++++++-------
 .../GeoModelWrite/WriteGeoModel.h             |  44 +-
 .../GeoModelWrite/src/WriteGeoModel.cpp       |  61 +-
 28 files changed, 1180 insertions(+), 461 deletions(-)
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_SimplePolygonBrep.cpp
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_SimplePolygonBrep.h
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trap.cpp
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trap.h
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trd.cpp
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trd.h
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tubs.cpp
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tubs.h
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_TwistedTrap.cpp
 create mode 100644 GeoModelIO/GeoModelRead/src/BuildGeoShapes_TwistedTrap.h

diff --git a/GeoModelExamples/HelloToy/CMakeLists.txt b/GeoModelExamples/HelloToy/CMakeLists.txt
index b1a570c52..8bb74b077 100644
--- a/GeoModelExamples/HelloToy/CMakeLists.txt
+++ b/GeoModelExamples/HelloToy/CMakeLists.txt
@@ -32,5 +32,5 @@ add_executable( helloToy_step1_write ${SRCS} )
 add_executable( helloToy_step2_read ${SRCS_READ} )
 
 # Link all needed libraries
-target_link_libraries( helloToy_step1_write GeoModelCore::GeoModelKernel GeoModelIO::GeoModelWrite )
+target_link_libraries( helloToy_step1_write GeoModelCore::GeoModelKernel GeoModelIO::GeoModelWrite GeoModelHelpers )
 target_link_libraries( helloToy_step2_read  GeoModelCore::GeoModelKernel GeoModelIO::GeoModelRead )
diff --git a/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp b/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp
index d1a4f83df..ada20952b 100644
--- a/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp
+++ b/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp
@@ -22,6 +22,7 @@
 #include "GeoModelKernel/GeoTrd.h"
 #include "GeoModelKernel/GeoTubs.h"
 #include "GeoModelKernel/GeoTwistedTrap.h"
+#include "GeoModelKernel/GeoSimplePolygonBrep.h"
 #include "GeoModelKernel/GeoPcon.h"
 #include "GeoModelKernel/GeoPgon.h"
 #include "GeoModelKernel/GeoLogVol.h"
@@ -44,6 +45,9 @@
 
 #include "GeoModelWrite/WriteGeoModel.h"
 
+#include "GeoModelHelpers/throwExcept.h"
+
+
 // Units
 #include "GeoModelKernel/Units.h"
 #define SYSTEM_OF_UNITS GeoModelKernelUnits // so we will get, e.g., 'SYSTEM_OF_UNITS::cm'
@@ -313,6 +317,31 @@ int main(int argc, char *argv[])
   toyPhys->add(nTwist);
   toyPhys->add(pTwist);
 
+  // Add a test GeoSimplePolygonBrep shape
+   const double DZ = 1 * SYSTEM_OF_UNITS::m;
+   const double xV1 = 1.5 * SYSTEM_OF_UNITS::m;
+   const double yV1 = 1.5 * SYSTEM_OF_UNITS::m;
+   const double xV2 = 3 * SYSTEM_OF_UNITS::m;
+   const double yV2 = 3 * SYSTEM_OF_UNITS::m;
+   const double xV3 = 4 * SYSTEM_OF_UNITS::m;
+   const double yV3 = 4 * SYSTEM_OF_UNITS::m;
+   GeoSimplePolygonBrep* sSimplePolygonBrep = new GeoSimplePolygonBrep(DZ);
+   sSimplePolygonBrep->addVertex(xV1, yV1);
+   sSimplePolygonBrep->addVertex(xV2, yV2);
+   sSimplePolygonBrep->addVertex(xV3, yV3);
+   if (!sSimplePolygonBrep->isValid())
+    {
+        THROW_EXCEPTION("ERROR! GeoSimplePolygonBrep shape is not valid!!");
+    }
+  GeoLogVol *lSimplePolygonBrep = new GeoLogVol("SimplePolygonBrep", sSimplePolygonBrep, steel);
+  GeoPhysVol *pSimplePolygonBrep = new GeoPhysVol(lSimplePolygonBrep);
+  GeoNameTag *nSimplePolygonBrep = new GeoNameTag("Shape-SimplePolygonBrep");
+  toyPhys->add(nSimplePolygonBrep);
+  toyPhys->add(pSimplePolygonBrep);
+
+
+
+
   //------------------------------------------------------------------------------------//
   // Writing the geometry to file
   //------------------------------------------------------------------------------------//
diff --git a/GeoModelExamples/HelloToy/step2_read_geo_and_published_nodes.cpp b/GeoModelExamples/HelloToy/step2_read_geo_and_published_nodes.cpp
index 978ed3911..e9baf8e5d 100644
--- a/GeoModelExamples/HelloToy/step2_read_geo_and_published_nodes.cpp
+++ b/GeoModelExamples/HelloToy/step2_read_geo_and_published_nodes.cpp
@@ -168,31 +168,43 @@ int main(int argc, char *argv[])
   unsigned int ii=0;
   std::cout << "\n\nPublished AlignableTransforms from the DB...\n";
   std::cout << "['xf' is the output of 'getTransform()']\n";
+  std::cout << "(Printing the first 3 only)" << std::endl;
   for ( auto const& [key, xf] : mapAXF ) 
   {
-      if(0==ii) std::cout << "[key type (compiler's code): '" << typeid(key).name() << "']\n";
-      std::cout << "\n\t--> key: " << key 
-                << " - AlignableTransform*: " << xf 
+    if (0 == ii)
+      std::cout << "[key type (compiler's code): '" << typeid(key).name() << "']\n";
+    if (ii < 3)
+    {
+
+      std::cout << "\n\t--> key: " << key
+                << " - AlignableTransform*: " << xf
                 << std::endl;
-      std::cout << "\txf:: "; GeoUtilFunctions::printTrf( xf->getTransform() );
-      ++ii;
-   }
-  
+      std::cout << "\txf:: ";
+      GeoUtilFunctions::printTrf(xf->getTransform());
+    }
+    ++ii;
+  }
+
   ii=0; // reset the counter
   std::cout << "\n\nPublished FullPhysVols from the DB...\n";
   std::cout << "['xf' is the output of 'getAbsoluteTransform()']\n";
+  std::cout << "(Printing the first 3 only)" << std::endl;
   for ( auto const& [key, vol] : mapFPV ) 
   {
       // GeoTrf::Transform3D xf = vol->getAbsoluteTransform(); // crashes
 
-      if(0==ii) std::cout << "[key type (compiler's code): '" << typeid(key).name() << "']\n";
-      std::cout << "\n\t--> key: " << key 
-                << " - GeoFullPhysVol*: " << vol 
-                << std::endl;
-      // std::cout << "\txf:"; GeoUtilFunctions::printTrf(vol->getAbsoluteTransform()); // crashes
+      if (0 == ii)
+        std::cout << "[key type (compiler's code): '" << typeid(key).name() << "']\n";
+      if (ii < 3)
+      {
+        std::cout << "\n\t--> key: " << key
+                  << " - GeoFullPhysVol*: " << vol
+                  << std::endl;
+        // std::cout << "\txf:"; GeoUtilFunctions::printTrf(vol->getAbsoluteTransform()); // crashes
+      }
       ++ii;
   }
-  
+
   std::cout << "Everything done." << std::endl;
 
   return 0;
diff --git a/GeoModelIO/GeoModelDBManager/CMakeLists.txt b/GeoModelIO/GeoModelDBManager/CMakeLists.txt
index 91182b1a7..d9f6d548f 100644
--- a/GeoModelIO/GeoModelDBManager/CMakeLists.txt
+++ b/GeoModelIO/GeoModelDBManager/CMakeLists.txt
@@ -14,7 +14,7 @@ file( GLOB HEADERS GeoModelDBManager/*.h )
 
 # Set up the library.
 add_library( GeoModelDBManager SHARED ${HEADERS} ${SOURCES} )
-target_link_libraries( GeoModelDBManager PRIVATE SQLite::SQLite3 GeoModelCppHelpers )
+target_link_libraries( GeoModelDBManager PRIVATE SQLite::SQLite3 GeoModelHelpers GeoModelCppHelpers )
 target_include_directories( GeoModelDBManager PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> )
diff --git a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
index b3d25cea5..148cce395 100644
--- a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
+++ b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
@@ -23,6 +23,7 @@
 #include <variant>
 #include <vector>
 #include <deque>
+#include <set>
 
 /**
  * \class GMDBManager
@@ -294,10 +295,13 @@ class GMDBManager {
     std::vector<std::variant<int, long, float, double, std::string>> getTableRecords_VecData(std::string tableName) const;
     std::vector<std::vector<std::variant<int, long, float, double, std::string>>> getTableRecords_VecVecData(std::string tableName) const;
 
-    // Test if a given table exists
-    // This requires the *full* table name (i.e. prefix_suffix)
+    //! Test if a given table exists
+    //! This requires the *full* table name (i.e. prefix_suffix)
     bool checkTable(std::string tableName) const;
 
+    //! Test if a table has been loaded from a DB, that is it exists in the cache
+    bool checkTableFromCache(const std::string_view tableName) const;
+
     /**
      * @brief Create a custom DB table to store auxiliary data.
      * @param tableName The name of the custom table
@@ -384,7 +388,8 @@ class GMDBManager {
     std::unordered_map<std::string, std::string> m_childType_tableName;
 
     /// cache for the list of tables in the DB
-    std::vector<std::string> m_cache_tables;
+    // std::vector<std::string> m_cache_tables;
+    std::set<std::string> m_cache_tables;
 
     std::unordered_map<unsigned int, std::string>
         m_cache_tableId_tableName;  /// cache for tableID-->tableName
diff --git a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
index 05931d482..161611fe8 100644
--- a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
+++ b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
@@ -25,6 +25,10 @@
 
 #include "GeoModelCppHelpers/GMCppHelpers.h"
 
+#include "GeoModelHelpers/throwExcept.h"
+#include "GeoModelHelpers/StringUtils.h"
+
+
 // include the 'fmt' library, which is hosted locally as header-only
 #define FMT_HEADER_ONLY 1  // to use 'fmt' header-only
 #include "fmt/format.h"
@@ -67,7 +71,7 @@ class GMDBManager::Imp {
 GMDBManager::GMDBManager(const std::string& path)
     : m_dbpath(path), m_dbIsOK(false), m_debug(false), m_d(new Imp(this)) {
     // Check if the user asked for running in serial or multi-threading mode
-    if ("" != GeoModelIO::CppHelper::getEnvVar("GEOMODEL_ENV_IO_DBMANAGER_DEBUG")) {
+    if ("" != GeoStrUtils::getEnvVar("GEOMODEL_ENV_IO_DBMANAGER_DEBUG")) {
         m_debug = true;
         std::cout << "You defined the GEOMODEL_IO_DEBUG variable, so you will "
                      "see a verbose output."
@@ -218,6 +222,7 @@ void GMDBManager::printAllRecords(const std::string& tableName) const {
 // TODO: fill a cache and returns that if asked a second time
 std::vector<std::vector<std::string>> GMDBManager::getTableRecords(
     std::string tableName) const {
+
     // container to be returned
     std::vector<std::vector<std::string>> records;
     // get the query statetement ready to be executed
@@ -276,6 +281,7 @@ std::vector<std::vector<std::string>> GMDBManager::getTableRecords(
 std::vector<std::vector<std::variant<int, long, float, double, std::string>>> GMDBManager::getTableRecords_VecVecData(
     std::string tableName) const
 {
+    
     // container to be returned
     std::vector<std::vector<std::variant<int, long, float, double, std::string>>> records;
     // get the query statetement ready to be executed
@@ -390,6 +396,9 @@ std::vector<std::vector<std::variant<int, long, float, double, std::string>>> GM
 std::vector<std::variant<int, long, float, double, std::string>> GMDBManager::getTableRecords_VecData(
     std::string tableName) const
 {
+    if (!checkTableFromCache(tableName)) {
+        THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
+    }
     // container to be returned
     std::vector<std::variant<int, long, float, double, std::string>> records;
     // get the query statetement ready to be executed
@@ -522,6 +531,10 @@ std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType(
     }
     else
     {
+        if (!checkTable(tableName))
+        {
+            THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
+        }
         out = getTableRecords(tableName);
     }
     return out;
@@ -532,6 +545,7 @@ std::vector<std::vector<std::variant<int, long, float, double, std::string>>> GM
 {
     std::vector<std::vector<std::variant<int, long, float, double, std::string>>> out;
     std::string tableName = getTableNameFromNodeType(nodeType);
+    
     if (tableName.empty())
     {
         std::mutex coutMutex;
@@ -549,15 +563,18 @@ std::vector<std::vector<std::variant<int, long, float, double, std::string>>> GM
     }
     else
     {
+        if (!checkTableFromCache(tableName))
+        {
+            THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
+        }
         out = getTableRecords_VecVecData(tableName);
     }
     return out;
 }
 DBRowsList GMDBManager::getTableFromTableName_VecVecData(
-    std::string tableNameInp)
+    std::string tableName)
 {
     std::vector<std::vector<std::variant<int, long, float, double, std::string>>> out;
-    std::string tableName = tableNameInp;
     if (tableName.empty())
     {
         std::mutex coutMutex;
@@ -570,20 +587,23 @@ DBRowsList GMDBManager::getTableFromTableName_VecVecData(
             "geometry file. Unless you know exactly what you are doing, "
             "please "
             "expect to see incomplete geometries or crashes.\n",
-            tableNameInp.c_str());
+            tableName.c_str());
         coutMutex.unlock();
     }
     else
     {
+        if (!checkTableFromCache(tableName))
+        {
+            THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
+        }
         out = getTableRecords_VecVecData(tableName);
     }
     return out;
 }
 std::vector<std::variant<int, long, float, double, std::string>> GMDBManager::getTableFromTableName_VecData(
-    std::string tableNameInp)
+    std::string tableName)
 {
     std::vector<std::variant<int, long, float, double, std::string>> out;
-    std::string tableName = tableNameInp;
     if (tableName.empty())
     {
         std::mutex coutMutex;
@@ -596,11 +616,15 @@ std::vector<std::variant<int, long, float, double, std::string>> GMDBManager::ge
             "geometry file. Unless you know exactly what you are doing, "
             "please "
             "expect to see incomplete geometries or crashes.\n",
-            tableNameInp.c_str());
+            tableName.c_str());
         coutMutex.unlock();
     }
     else
     {
+        if (!checkTableFromCache(tableName))
+        {
+            THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
+        }
         out = getTableRecords_VecData(tableName);
     }
     return out;
@@ -1252,6 +1276,20 @@ bool GMDBManager::initDB() {
     return tablesOK;
 }
 
+bool GMDBManager::checkTableFromCache(const std::string_view tableName) const
+{
+    std::string tableNameStr{tableName};
+    if (m_cache_tables.size() == 0)
+    {
+        return false;
+    }
+    else if (m_cache_tables.find(tableNameStr) != m_cache_tables.end())
+    {
+        return true;
+    }
+    return false;
+}
+
 void GMDBManager::printAllDBTables() {
     if (m_cache_tables.size() == 0) {
         getAllDBTables();  // load tables and build the cache
@@ -1261,7 +1299,7 @@ void GMDBManager::printAllDBTables() {
 
 void GMDBManager::getAllDBTables() {
     std::string tableName;
-    std::vector<std::string> tables;
+    std::set<std::string> tables;
     // define a query string containing the necessary SQL instructions
     std::string queryStr =
         "SELECT name FROM sqlite_master WHERE type ='table' AND name NOT "
@@ -1279,7 +1317,7 @@ void GMDBManager::getAllDBTables() {
         tableName = std::string(
             reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
         // std::cout << "tableName: " << tableName << std::endl; // debug
-        tables.push_back(tableName);
+        tables.insert(tableName);
     }
     if (rc != SQLITE_DONE) {
         std::string errmsg(sqlite3_errmsg(m_d->m_dbSqlite));
@@ -1338,7 +1376,10 @@ std::vector<std::vector<std::string>> GMDBManager::getPublishedFPVTable(
         tableName += "_";
         tableName += suffix;
     }
-
+    if (!checkTableFromCache(tableName))
+    {
+        THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
+    }
     return getTableRecords(tableName);
 }
 // TODO: currently, we retrieve published data as strings, but we want to
@@ -1351,7 +1392,10 @@ std::vector<std::vector<std::string>> GMDBManager::getPublishedAXFTable(
         tableName += "_";
         tableName += suffix;
     }
-
+    if (!checkTableFromCache(tableName))
+    {
+        THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
+    }
     return getTableRecords(tableName);
 }
 
@@ -1600,6 +1644,19 @@ bool GMDBManager::createTables() {
         tab[0], tab[1], tab[2], tab[3], tab[4]);
     rc = execQuery(queryStr);
     tab.clear();
+    
+    // create a table to store the numeric data used in GeoPcon shapes
+    tableName = "Shapes_SimplePolygonBrep_Data";
+    tab.push_back(tableName);
+    tab.push_back("id");
+    tab.push_back("XVertex");
+    tab.push_back("YVertex");
+    storeTableColumnNames(tab);
+    queryStr = fmt::format(
+        "create table {0}({1} integer primary key, {2} real, {3} real )",
+        tab[0], tab[1], tab[2], tab[3]);
+    rc = execQuery(queryStr);
+    tab.clear();
 
 
     // create a table to store information about the 'root' volume (also
@@ -1940,13 +1997,33 @@ bool GMDBManager::createTables() {
     tab.push_back("computedVolume");
     tab.push_back("SPhi");
     tab.push_back("DPhi");
+    tab.push_back("NSides");
     tab.push_back("NZPlanes");
     tab.push_back("dataStart");
     tab.push_back("dataEnd");
     storeTableColumnNames(tab);
     queryStr = fmt::format(
-        "create table {0}({1} integer primary key, {2} real, {3} real, {4} real, {5} integer, {6} integer, {7} integer )",
-        tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7]);
+        "create table {0}({1} integer primary key, {2} real, {3} real, {4} real, {5} integer, {6} integer, {7} integer, {8} integer )",
+        tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7], tab[8]);
+    if (0 == (rc = execQuery(queryStr))) {
+        storeNodeType(geoNode, tableName);
+    }
+    tab.clear();
+    // Shapes-SimplePolygonBrep table
+    geoNode = "GeoSimplePolygonBrep";
+    tableName = "Shapes_SimplePolygonBrep";
+    m_childType_tableName[geoNode] = tableName;
+    tab.push_back(tableName);
+    tab.push_back("id");
+    tab.push_back("computedVolume");
+    tab.push_back("DZ");
+    tab.push_back("NVertices");
+    tab.push_back("dataStart");
+    tab.push_back("dataEnd");
+    storeTableColumnNames(tab);
+    queryStr = fmt::format(
+        "create table {0}({1} integer primary key, {2} real, {3} real, {4} integer, {5} integer, {6} integer )",
+        tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6]);
     if (0 == (rc = execQuery(queryStr))) {
         storeNodeType(geoNode, tableName);
     }
diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
index 1ab56e484..ceb946f71 100644
--- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
+++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
@@ -92,9 +92,14 @@ class BuildGeoShapes_Box;
 class BuildGeoShapes_Tube;
 class BuildGeoShapes_Cons;
 class BuildGeoShapes_Para;
+class BuildGeoShapes_Trap;
+class BuildGeoShapes_Trd;
+class BuildGeoShapes_Tubs;
+class BuildGeoShapes_TwistedTrap;
 
 class BuildGeoShapes_Pcon;
 class BuildGeoShapes_Pgon;
+class BuildGeoShapes_SimplePolygonBrep;
 
 // type definitions
 typedef const GeoXF::Function& TRANSFUNCTION;
@@ -172,9 +177,14 @@ class ReadGeoModel {
     void buildAllShapes_Tube();
     void buildAllShapes_Cons();
     void buildAllShapes_Para();
-    
+    void buildAllShapes_Trap();
+    void buildAllShapes_Trd();
+    void buildAllShapes_Tubs();
+    void buildAllShapes_TwistedTrap();
+
     void buildAllShapes_Pcon();
     void buildAllShapes_Pgon();
+    void buildAllShapes_SimplePolygonBrep();
 
     void buildAllShapes();
     void buildAllElements();
@@ -340,9 +350,14 @@ class ReadGeoModel {
     BuildGeoShapes_Tube* m_builderShape_Tube;
     BuildGeoShapes_Cons* m_builderShape_Cons;
     BuildGeoShapes_Para* m_builderShape_Para;
+    BuildGeoShapes_Trap* m_builderShape_Trap;
+    BuildGeoShapes_Trd* m_builderShape_Trd;
+    BuildGeoShapes_Tubs* m_builderShape_Tubs;
+    BuildGeoShapes_TwistedTrap* m_builderShape_TwistedTrap;
 
     BuildGeoShapes_Pcon* m_builderShape_Pcon;
     BuildGeoShapes_Pgon* m_builderShape_Pgon;
+    BuildGeoShapes_SimplePolygonBrep* m_builderShape_SimplePolygonBrep;
 
 
     //! containers to store the list of GeoModel nodes coming from the DB
@@ -360,24 +375,30 @@ class ReadGeoModel {
     std::vector<std::vector<std::string>> m_shapes;
     std::vector<std::vector<std::string>> m_allchildren;
 
-    // std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_logVols;
     DBRowsList m_logVols;
 
     // containers to store shapes' parameters
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Box;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Tube;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Cons;
+    DBRowsList m_shapes_Box;
+    DBRowsList m_shapes_Tube;
+    DBRowsList m_shapes_Cons;
     DBRowsList m_shapes_Para;
-
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Pcon;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Pgon;
+    DBRowsList m_shapes_Trap;
+    DBRowsList m_shapes_Trd;
+    DBRowsList m_shapes_Tubs;
+    DBRowsList m_shapes_TwistedTrap;
+
+    DBRowsList m_shapes_Pcon;
+    DBRowsList m_shapes_Pgon;
+    DBRowsList m_shapes_SimplePolygonBrep;
     
-    // containers to store shapes' data, for shapes with a variable number of build parameters
+    // containers to store shapes' data, 
+    // for those shapes with a variable number of build parameters
     DBRowsList m_shapes_Pcon_data;
     DBRowsList m_shapes_Pgon_data;
+    DBRowsList m_shapes_SimplePolygonBrep_data;
 
-    // std::vector<std::vector<std::string>> m_functions;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_functions;
+    // containers to store Functions and their related data
+    DBRowsList m_functions;
     std::deque<double> m_funcExprData;
 
 
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes.cpp
index f29b3fffd..714b16096 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes.cpp
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes.cpp
@@ -34,6 +34,7 @@ void BuildGeoShapes::storeBuiltShape(const unsigned id, GeoShape* nodePtr) {
     m_memMapShapes[id] = nodePtr;
 }
 GeoShape* BuildGeoShapes::getBuiltShape(const unsigned id) {
+    if (!m_memMapShapes.size()) return nullptr;
     return m_memMapShapes[id];  // this is a map, and 'id' is the key
 }
 
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes.h
index 14be15fac..3713c4beb 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes.h
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes.h
@@ -25,7 +25,7 @@ class GeoShape;
 class BuildGeoShapes
 {
 protected:
-  std::unordered_map<unsigned, GeoShape *> m_memMapShapes;
+  std::unordered_map<unsigned, GeoShape *> m_memMapShapes{};
   std::string m_shapeType;
   DBRowsList m_shape_data;
 
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.cpp
index 9645e2a78..ebab087d5 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.cpp
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.cpp
@@ -3,7 +3,7 @@
 */
 
 /*
- * Created on: May 7, 2024
+ * Created on: May, 2024
  * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
  */
 
@@ -26,10 +26,10 @@ void BuildGeoShapes_Cons::buildShape(const std::vector<std::variant<int, long, f
     const double RMin1 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Cons:RMin1");
     const double RMin2 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Cons:RMin2");
     const double RMax1 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:RMax1");
-    const double RMax2 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:RMax2");
-    const double DZ = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:DZ");
-    const double SPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:SPhi");
-    const double DPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:DPhi");
+    const double RMax2 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[5], "Cons:RMax2");
+    const double DZ = GeoModelHelpers::variantHelper::getFromVariant_Double(row[6], "Cons:DZ");
+    const double SPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[7], "Cons:SPhi");
+    const double DPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[8], "Cons:DPhi");
 
     GeoCons *shape = new GeoCons(RMin1, RMin2, RMax1, RMax2, DZ, SPhi, DPhi);
 
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.h
index b54b849b4..e414ff8c9 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.h
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.h
@@ -5,7 +5,7 @@
 /*
  * BuildGeoShapes_Cons.h
  *
- * Created on: May 7, 2024
+ * Created on: May, 2024
  * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
  *
  */
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Para.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Para.cpp
index 0aea59eaa..6b07a2c97 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Para.cpp
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Para.cpp
@@ -26,10 +26,10 @@ void BuildGeoShapes_Para::buildShape(const std::vector<std::variant<int, long, f
   // shape parameters
   double XHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Para:XHalfLength");
   double YHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Para:YHalfLength");
-  double ZHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Para:ZHalfLength");
-  double Alpha = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Para:Alpha");
-  double Theta = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Para:Theta");
-  double Phi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Para:Phi");
+  double ZHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Para:ZHalfLength");
+  double Alpha = GeoModelHelpers::variantHelper::getFromVariant_Double(row[5], "Para:Alpha");
+  double Theta = GeoModelHelpers::variantHelper::getFromVariant_Double(row[6], "Para:Theta");
+  double Phi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[7], "Para:Phi");
 
   GeoPara *shape = new GeoPara(XHalfLength, YHalfLength, ZHalfLength, Alpha, Theta,
                                Phi);
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pgon.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pgon.cpp
index fd27213f7..3391eb0f9 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pgon.cpp
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pgon.cpp
@@ -23,20 +23,18 @@ void BuildGeoShapes_Pgon::buildShape(const std::vector<std::variant<int, long, f
     }
 
     // === get shape numeric data from the DB row
-
     // shape ID
     const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Pgon:shapeID");
     // shape volume
     const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "Pgon:shapeVolume");
-
     // shape parameters
     const double SPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Pgon:SPhi");
     const double DPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Pgon:DPhi");
     const int NSides = GeoModelHelpers::variantHelper::getFromVariant_Int(row[4], "Pgon:NSides");
-    const int NZPlanes = GeoModelHelpers::variantHelper::getFromVariant_Int(row[4], "Pgon:NZPlanes");
+    const int NZPlanes = GeoModelHelpers::variantHelper::getFromVariant_Int(row[5], "Pgon:NZPlanes");
     // pointers to variable shape data stored in a separate table
-    const int dataStart = GeoModelHelpers::variantHelper::getFromVariant_Int(row[5], "Pgon:dataStart");
-    const int dataEnd = GeoModelHelpers::variantHelper::getFromVariant_Int(row[6], "Pgon:dataEnd");
+    const int dataStart = GeoModelHelpers::variantHelper::getFromVariant_Int(row[6], "Pgon:dataStart");
+    const int dataEnd = GeoModelHelpers::variantHelper::getFromVariant_Int(row[7], "Pgon:dataEnd");
 
     // build the basic GeoPgon shape
     GeoPgon *shape = new GeoPgon(SPhi, DPhi, NSides);
@@ -44,7 +42,7 @@ void BuildGeoShapes_Pgon::buildShape(const std::vector<std::variant<int, long, f
     // and now loop over the additional shape's data, 
     // to get the parameters of all Z planes
 
-    // get ZPlanes' data, extract subvector
+    // extract subvector
     // NOTE: we use (dataStart-1) to cope with the difference between the DB rows starting from '1', 
     //       which is what the 'dataStart' stores, and the vector items, which start '0'; 
     //       also, the constructor of the sub-vector takes the element from 'begin+dataStart-1' included
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_SimplePolygonBrep.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_SimplePolygonBrep.cpp
new file mode 100644
index 000000000..131c2760d
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_SimplePolygonBrep.cpp
@@ -0,0 +1,81 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ */
+
+#include "BuildGeoShapes_SimplePolygonBrep.h"
+
+#include "GeoModelKernel/GeoSimplePolygonBrep.h"
+#include "GeoModelHelpers/variantHelpers.h"
+#include "GeoModelHelpers/throwExcept.h"
+
+#include <vector>
+#include <iostream>
+
+void BuildGeoShapes_SimplePolygonBrep::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row)
+{
+    if (!(m_shape_data.size()))
+    {
+        THROW_EXCEPTION("ERROR! GeoSimplePolygonBrep shape has no ZPlanes data!! [m_shape_data.size() == 0]");
+    }
+
+    // === get shape numeric data from the DB row
+    // shape ID
+    const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "SimplePolygonBrep:shapeID");
+    // shape volume
+    const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "SimplePolygonBrep:shapeVolume");
+    // shape parameters
+    const double DZ = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "SimplePolygonBrep:DZ");
+    const unsigned int NVertices = GeoModelHelpers::variantHelper::getFromVariant_Int(row[3], "SimplePolygonBrep:NVertices");
+    // pointers to variable shape data stored in a separate table
+    const int dataStart = GeoModelHelpers::variantHelper::getFromVariant_Int(row[4], "SimplePolygonBrep:dataStart");
+    const int dataEnd = GeoModelHelpers::variantHelper::getFromVariant_Int(row[5], "SimplePolygonBrep:dataEnd");
+
+    // build the basic GeoSimplePolygonBrep shape
+    GeoSimplePolygonBrep *shape = new GeoSimplePolygonBrep(DZ);
+
+    // and now loop over the additional shape's data,
+    // to get the parameters of all vertices
+
+    // extract subvector
+    // NOTE: we use (dataStart-1) to cope with the difference between the DB rows starting from '1',
+    //       which is what the 'dataStart' stores, and the vector items, which start '0';
+    //       also, the constructor of the sub-vector takes the element from 'begin+dataStart-1' included
+    //       and 'begin+dataEnd' excluded.
+    const DBRowsList thisShapeData(m_shape_data.begin() + (dataStart - 1),
+                                   m_shape_data.begin() + (dataEnd));
+    if (!(thisShapeData.size()))
+    {
+        THROW_EXCEPTION("ERROR! GeoSimplePolygonBrep shape ZPlanes data have not been retrieved!!");
+    }
+    if (!(NVertices == thisShapeData.size()))
+    {
+        THROW_EXCEPTION("ERROR! GeoSimplePolygonBrep shape : size of ZPlanes data does not correspond to the number of ZPlanes declared!!");
+    }
+    // loop over the data defining the ZPlanes
+    for (const DBRowEntry &dataRow : thisShapeData)
+    {
+        const double xV = GeoModelHelpers::variantHelper::getFromVariant_Double(dataRow[1], "SimplePolygonBrep:data_xV");
+        const double yV = GeoModelHelpers::variantHelper::getFromVariant_Double(dataRow[2], "SimplePolygonBrep:data_yV");
+        // add a Z plane to the GeoSimplePolygonBrep
+        shape->addVertex(xV, yV);
+    }
+
+    // sanity checks on the resulting SimplePolygonBrep shape
+    if (shape->getNVertices() != NVertices)
+    {
+        THROW_EXCEPTION("ERROR! GeoSimplePolygonBrep actual number of vertices: " + std::to_string(shape->getNVertices()) + " is not equal to the original size! --> " + std::to_string(NVertices));
+    }
+    if (!shape->isValid())
+    {
+        THROW_EXCEPTION("ERROR! GeoSimplePolygonBrep shape is not valid!!");
+    }
+
+    storeBuiltShape(shapeId, shape);
+
+    return;
+}
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_SimplePolygonBrep.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_SimplePolygonBrep.h
new file mode 100644
index 000000000..c7442b675
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_SimplePolygonBrep.h
@@ -0,0 +1,30 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * BuildGeoShapes_SimplePolygonBrep.h
+ *
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ *
+ */
+
+#ifndef GEOMODELREAD_BuildGeoShapes_SimplePolygonBrep_H
+#define GEOMODELREAD_BuildGeoShapes_SimplePolygonBrep_H
+
+#include "BuildGeoShapes.h"
+
+#include "GeoModelDBManager/definitions.h"
+
+#include <vector>
+#include <variant>
+
+class BuildGeoShapes_SimplePolygonBrep : public BuildGeoShapes
+{
+public:
+  BuildGeoShapes_SimplePolygonBrep(const unsigned size, DBRowsList shapeData):BuildGeoShapes("SimplePolygonBrep", size, shapeData){};
+  void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override;
+};
+
+#endif
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trap.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trap.cpp
new file mode 100644
index 000000000..2997d8134
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trap.cpp
@@ -0,0 +1,44 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ */
+
+#include "BuildGeoShapes_Trap.h"
+
+#include "GeoModelKernel/GeoTrap.h"
+#include "GeoModelHelpers/variantHelpers.h"
+
+#include <vector>
+#include <iostream>
+
+void BuildGeoShapes_Trap::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row)
+{
+  // === get shape numeric data from the DB row
+  // shape ID
+  const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Trap:shapeID");
+  // shape volume
+  const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "Trap:shapeVolume");
+  // shape parameters
+  double ZHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Trap:ZHalfLength");
+  double Theta = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Trap:Theta");
+  double Phi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Trap:Phi");
+  double Dydzn = GeoModelHelpers::variantHelper::getFromVariant_Double(row[5], "Trap:Dydzn");
+  double Dxdyndzn = GeoModelHelpers::variantHelper::getFromVariant_Double(row[6], "Trap:Dxdyndzn");
+  double Dxdypdzn = GeoModelHelpers::variantHelper::getFromVariant_Double(row[7], "Trap:Dxdypdzn");
+  double Angleydzn = GeoModelHelpers::variantHelper::getFromVariant_Double(row[8], "Trap:Angleydzn");
+  double Dydzp = GeoModelHelpers::variantHelper::getFromVariant_Double(row[9], "Trap:Dydzp");
+  double Dxdyndzp = GeoModelHelpers::variantHelper::getFromVariant_Double(row[10], "Trap:Dxdyndzp");
+  double Dxdypdzp = GeoModelHelpers::variantHelper::getFromVariant_Double(row[11], "Trap:Dxdypdzp");
+  double Angleydzp = GeoModelHelpers::variantHelper::getFromVariant_Double(row[12], "Trap:Angleydzp");
+
+  GeoShape *shape = new GeoTrap(ZHalfLength, Theta, Phi, Dydzn, Dxdyndzn, Dxdypdzn,
+                                Angleydzn, Dydzp, Dxdyndzp, Dxdypdzp, Angleydzp);
+
+  storeBuiltShape(shapeId, shape);
+
+  return;
+}
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trap.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trap.h
new file mode 100644
index 000000000..f42b86c67
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trap.h
@@ -0,0 +1,29 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * BuildGeoShapes_Trap.h
+ *
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ *
+ */
+
+#ifndef GEOMODELREAD_BuildGeoShapes_Trap_H
+#define GEOMODELREAD_BuildGeoShapes_Trap_H
+
+#include "BuildGeoShapes.h"
+
+#include <vector>
+#include <variant>
+#include <string>
+
+class BuildGeoShapes_Trap : public BuildGeoShapes
+{
+public:
+  BuildGeoShapes_Trap(const unsigned size):BuildGeoShapes("Trap", size){};
+  void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override;
+};
+
+#endif
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trd.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trd.cpp
new file mode 100644
index 000000000..21454f0de
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trd.cpp
@@ -0,0 +1,37 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ */
+
+#include "BuildGeoShapes_Trd.h"
+
+#include "GeoModelKernel/GeoTrd.h"
+#include "GeoModelHelpers/variantHelpers.h"
+
+#include <vector>
+#include <iostream>
+
+void BuildGeoShapes_Trd::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row)
+{
+  // === get shape numeric data from the DB row
+  // shape ID
+  const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Trd:shapeID");
+  // shape volume
+  const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "Trd:shapeVolume");
+  // shape parameters
+  double XHalfLength1 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Trd:XHalfLength1");
+  double XHalfLength2 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Trd:XHalfLength2");
+  double YHalfLength1 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Trd:YHalfLength1");
+  double YHalfLength2 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[5], "Trd:YHalfLength2");
+  double ZHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[6], "Trd:ZHalfLength");
+  
+  GeoShape *shape = new GeoTrd(XHalfLength1, XHalfLength2, YHalfLength1, YHalfLength2, ZHalfLength);
+
+  storeBuiltShape(shapeId, shape);
+
+  return;
+}
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trd.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trd.h
new file mode 100644
index 000000000..caf4a47dc
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Trd.h
@@ -0,0 +1,29 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * BuildGeoShapes_Trd.h
+ *
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ *
+ */
+
+#ifndef GEOMODELREAD_BuildGeoShapes_Trd_H
+#define GEOMODELREAD_BuildGeoShapes_Trd_H
+
+#include "BuildGeoShapes.h"
+
+#include <vector>
+#include <variant>
+#include <string>
+
+class BuildGeoShapes_Trd : public BuildGeoShapes
+{
+public:
+  BuildGeoShapes_Trd(const unsigned size):BuildGeoShapes("Trd", size){};
+  void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override;
+};
+
+#endif
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.cpp
index 689782127..4e9659650 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.cpp
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.cpp
@@ -3,7 +3,7 @@
 */
 
 /*
- * Created on: May 7, 2024
+ * Created on: May, 2024
  * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
  */
 
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.h
index fa1933e12..5087d9287 100644
--- a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.h
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.h
@@ -5,7 +5,7 @@
 /*
  * BuildGeoShapes_Tube.h
  *
- * Created on: May 7, 2024
+ * Created on: May, 2024
  * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
  *
  */
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tubs.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tubs.cpp
new file mode 100644
index 000000000..c0b654f51
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tubs.cpp
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ */
+
+#include "BuildGeoShapes_Tubs.h"
+
+#include "GeoModelKernel/GeoTubs.h"
+#include "GeoModelHelpers/variantHelpers.h"
+
+#include <vector>
+#include <iostream>
+
+void BuildGeoShapes_Tubs::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row)
+{
+  // === get shape numeric data from the DB row
+  // shape ID
+  const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Tubs:shapeID");
+  // shape volume
+  const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "Tubs:shapeVolume");
+  // shape parameters
+  double RMin = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Tubs:RMin");
+  double RMax = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Tubs:RMax");
+  double ZHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Tubs:ZHalfLength");
+  double SPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[5], "Tubs:SPhi");
+  double DPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[6], "Tubs:DPhi");
+  GeoShape *shape = new GeoTubs(RMin, RMax, ZHalfLength, SPhi, DPhi);
+
+  storeBuiltShape(shapeId, shape);
+
+  return;
+}
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tubs.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tubs.h
new file mode 100644
index 000000000..6e3e603e6
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tubs.h
@@ -0,0 +1,28 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * BuildGeoShapes_Tubs.h
+ *
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ *
+ */
+
+#ifndef GEOMODELREAD_BuildGeoShapes_Tubs_H
+#define GEOMODELREAD_BuildGeoShapes_Tubs_H
+
+#include "BuildGeoShapes.h"
+
+#include <vector>
+#include <variant>
+
+class BuildGeoShapes_Tubs : public BuildGeoShapes
+{
+public:
+  BuildGeoShapes_Tubs(const unsigned size):BuildGeoShapes("Tubs", size){};
+  void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override;
+};
+
+#endif
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_TwistedTrap.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_TwistedTrap.cpp
new file mode 100644
index 000000000..7754b437e
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_TwistedTrap.cpp
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ */
+
+#include "BuildGeoShapes_TwistedTrap.h"
+
+#include "GeoModelKernel/GeoTwistedTrap.h"
+#include "GeoModelHelpers/variantHelpers.h"
+
+#include <vector>
+#include <iostream>
+
+void BuildGeoShapes_TwistedTrap::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row)
+{
+  // === get shape numeric data from the DB row
+  // shape ID
+  const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "TwistedTrap:shapeID");
+  // shape volume
+  const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "TwistedTrap:shapeVolume");
+  // shape parameters
+  double PhiTwist = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "TwistedTrap:PhiTwist");
+  double ZHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "TwistedTrap:ZHalfLength");
+  double Theta = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "TwistedTrap:Theta");
+  double Phi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[5], "TwistedTrap:Phi");
+  double DY1HalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[6], "TwistedTrap:DY1HalfLength");
+  double DX1HalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[7], "TwistedTrap:DX1HalfLength");
+  double DX2HalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[8], "TwistedTrap:DX2HalfLength");
+  double DY2HalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[9], "TwistedTrap:DY2HalfLength");
+  double DX3HalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[10], "TwistedTrap:DX3HalfLength");
+  double DX4HalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[11], "TwistedTrap:DX4HalfLength");
+  double DTiltAngleAlpha = GeoModelHelpers::variantHelper::getFromVariant_Double(row[12], "TwistedTrap:DTiltAngleAlpha");
+
+  GeoShape *shape =
+      new GeoTwistedTrap(PhiTwist, ZHalfLength, Theta, Phi, DY1HalfLength,
+                         DX1HalfLength, DX2HalfLength, DY2HalfLength,
+                         DX3HalfLength, DX4HalfLength, DTiltAngleAlpha);
+
+  storeBuiltShape(shapeId, shape);
+
+  return;
+}
diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_TwistedTrap.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_TwistedTrap.h
new file mode 100644
index 000000000..72b8c98a5
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_TwistedTrap.h
@@ -0,0 +1,28 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*
+ * BuildGeoShapes_TwistedTrap.h
+ *
+ * Created on: May, 2024
+ * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+ *
+ */
+
+#ifndef GEOMODELREAD_BuildGeoShapes_TwistedTrap_H
+#define GEOMODELREAD_BuildGeoShapes_TwistedTrap_H
+
+#include "BuildGeoShapes.h"
+
+#include <vector>
+#include <variant>
+
+class BuildGeoShapes_TwistedTrap : public BuildGeoShapes
+{
+public:
+  BuildGeoShapes_TwistedTrap(const unsigned size):BuildGeoShapes("TwistedTrap", size){};
+  void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override;
+};
+
+#endif
diff --git a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
index 0d72ff7e8..d65fee431 100644
--- a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
+++ b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 /*
@@ -8,7 +8,7 @@
  *  Created on: May 20, 2016
  *  Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
  *
- * major updates:
+ * Major updates:
  *  - Feb 2019, R.M.Bianchi
  *  - Mar 2020, R.M.Bianchi
  *  - Mar 2020, boudreau
@@ -23,6 +23,8 @@
  *              The copyNumber was wrongly used together with tableID and volID
  *              For details, see:
  *              https://gitlab.cern.ch/GeoModelDev/GeoModel/-/issues/39
+ *  - May 2024, R.M.Bianchi <riccardo.maria.bianchi@cern.ch>
+ *              Major re-write: moved to the new DB schema based on numeric data
  */
 
 // local includes
@@ -32,6 +34,11 @@
 #include "BuildGeoShapes_Para.h"
 #include "BuildGeoShapes_Pcon.h"
 #include "BuildGeoShapes_Pgon.h"
+#include "BuildGeoShapes_Trap.h"
+#include "BuildGeoShapes_Trd.h"
+#include "BuildGeoShapes_Tubs.h"
+#include "BuildGeoShapes_TwistedTrap.h"
+#include "BuildGeoShapes_SimplePolygonBrep.h"
 
 #include "GeoModelRead/ReadGeoModel.h"
 
@@ -220,10 +227,22 @@ ReadGeoModel::~ReadGeoModel() {
     delete m_builderShape_Tube;
     delete m_builderShape_Pcon;
     delete m_builderShape_Cons;
+    delete m_builderShape_Pgon;
+    delete m_builderShape_Trap;
+    delete m_builderShape_Trd;
+    delete m_builderShape_Tubs;
+    delete m_builderShape_TwistedTrap;
+    delete m_builderShape_SimplePolygonBrep;
     m_builderShape_Box = nullptr;
     m_builderShape_Tube = nullptr;
     m_builderShape_Pcon = nullptr;
     m_builderShape_Cons = nullptr;
+    m_builderShape_Pgon = nullptr;
+    m_builderShape_Trap = nullptr;
+    m_builderShape_Trd = nullptr;
+    m_builderShape_Tubs = nullptr;
+    m_builderShape_TwistedTrap = nullptr;
+    m_builderShape_SimplePolygonBrep = nullptr;
 }
 
 // FIXME: TODO: move to an utility class
@@ -284,13 +303,19 @@ void ReadGeoModel::loadDB() {
     m_shapes_Tube = m_dbManager->getTableFromNodeType_VecVecData("GeoTube");
     m_shapes_Cons = m_dbManager->getTableFromNodeType_VecVecData("GeoCons");
     m_shapes_Para = m_dbManager->getTableFromNodeType_VecVecData("GeoPara");
+    m_shapes_Trap = m_dbManager->getTableFromNodeType_VecVecData("GeoTrap");
+    m_shapes_Trd = m_dbManager->getTableFromNodeType_VecVecData("GeoTrd");
+    m_shapes_Tubs = m_dbManager->getTableFromNodeType_VecVecData("GeoTubs");
+    m_shapes_TwistedTrap = m_dbManager->getTableFromNodeType_VecVecData("GeoTwistedTrap");
     
     m_shapes_Pcon = m_dbManager->getTableFromNodeType_VecVecData("GeoPcon");
     m_shapes_Pgon = m_dbManager->getTableFromNodeType_VecVecData("GeoPgon");
+    m_shapes_SimplePolygonBrep = m_dbManager->getTableFromNodeType_VecVecData("GeoSimplePolygonBrep");
 
     // shapes' data, when needed by shapes that have variable numbers of build parameters
     m_shapes_Pcon_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_Pcon_Data");
     m_shapes_Pgon_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_Pgon_Data");
+    m_shapes_SimplePolygonBrep_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_SimplePolygonBrep_Data");
 
     // get the Function's expression data
     // m_funcExprData = m_dbManager->getTableFromTableNameVecVecData("FuncExprData");
@@ -344,6 +369,11 @@ GeoVPhysVol* ReadGeoModel::buildGeoModelPrivate() {
         std::thread t18(&ReadGeoModel::buildAllShapes_Cons, this);
         std::thread t19(&ReadGeoModel::buildAllShapes_Para, this);
         std::thread t20(&ReadGeoModel::buildAllShapes_Pgon, this);
+        std::thread t21(&ReadGeoModel::buildAllShapes_Trap, this);
+        std::thread t22(&ReadGeoModel::buildAllShapes_Trd, this);
+        std::thread t23(&ReadGeoModel::buildAllShapes_Tubs, this);
+        std::thread t24(&ReadGeoModel::buildAllShapes_TwistedTrap, this);
+        std::thread t25(&ReadGeoModel::buildAllShapes_SimplePolygonBrep, this);
 
         t2.join();  // ok, all Elements have been built
         // needs Elements
@@ -352,9 +382,15 @@ GeoVPhysVol* ReadGeoModel::buildGeoModelPrivate() {
         t1.join();  // ok, all Shapes have been built
         t15.join();  // ok, all Shapes-Box have been built
         t16.join();  // ok, all Shapes-Tube have been built
-        t17.join();  // ok, all Shapes-Tube have been built
-        t18.join();  // ok, all Shapes-Tube have been built
-        t19.join();  // ok, all Shapes-Tube have been built
+        t17.join();  // ok, all Shapes-Pcon have been built
+        t18.join();  // ok, all Shapes-Cons have been built
+        t19.join();  // ok, all Shapes-Para have been built
+        t20.join();  // ok, all Shapes-Pgon have been built
+        t21.join();  // ok, all Shapes-Trap have been built
+        t22.join();  // ok, all Shapes-Trd have been built
+        t23.join();  // ok, all Shapes-Tubs have been built
+        t24.join();  // ok, all Shapes-TwistedTrap have been built
+        t25.join();  // ok, all Shapes-SimplePolygonBrep have been built
         t3.join();  // ok, all Materials have been built
         // needs Shapes and Materials
         std::thread t4(&ReadGeoModel::buildAllLogVols, this);
@@ -393,8 +429,13 @@ GeoVPhysVol* ReadGeoModel::buildGeoModelPrivate() {
         buildAllShapes_Tube();
         buildAllShapes_Pcon();
         buildAllShapes_Pgon();
+        buildAllShapes_SimplePolygonBrep();
         buildAllShapes_Cons();
         buildAllShapes_Para();
+        buildAllShapes_Trap();
+        buildAllShapes_Trd();
+        buildAllShapes_Tubs();
+        buildAllShapes_TwistedTrap();
         buildAllMaterials();
         buildAllLogVols();
         buildAllPhysVols();
@@ -477,8 +518,8 @@ void ReadGeoModel::buildAllShapes() {
     if (nSize > 0) std::cout << "All " << nSize << " Shapes have been built!\n";
 }
 
-//! Iterate over the list of shapes, build them all, and store their
-//! pointers
+//! Iterate over the list of GeoBox shape nodes, build them all, 
+//! and store their pointers
 void ReadGeoModel::buildAllShapes_Box()
 {
     if (m_loglevel >= 1) {
@@ -500,8 +541,8 @@ void ReadGeoModel::buildAllShapes_Box()
         std::cout << "All " << nSize << " Shapes-Box have been built!\n";
     }
 }
-//! Iterate over the list of shapes, build them all, and store their
-//! pointers
+//! Iterate over the list of GeoTube shape nodes, build them all, 
+//! and store their pointers
 void ReadGeoModel::buildAllShapes_Tube()
 {
     // create a builder and reserve size of memory map
@@ -519,8 +560,8 @@ void ReadGeoModel::buildAllShapes_Tube()
     }
 }
 
-//! Iterate over the list of shapes, build them all, and store their
-//! pointers
+//! Iterate over the list of GeoCons shape nodes, build them all, 
+//! and store their pointers
 void ReadGeoModel::buildAllShapes_Cons()
 {
     // create a builder and reserve size of memory map
@@ -537,8 +578,8 @@ void ReadGeoModel::buildAllShapes_Cons()
         std::cout << "All " << nSize << " Shapes-Cons have been built!\n";
     }
 }
-//! Iterate over the list of GeoPara shapes, build them all, and store their
-//! pointers
+//! Iterate over the list of GeoPara shape nodes, build them all, 
+//! and store their pointers
 void ReadGeoModel::buildAllShapes_Para()
 {
     // create a builder and reserve size of memory map
@@ -555,9 +596,80 @@ void ReadGeoModel::buildAllShapes_Para()
         std::cout << "All " << nSize << " Shapes-Para have been built!\n";
     }
 }
-
-//! Iterate over the list of shapes, build them all, and store their
-//! pointers
+//! Iterate over the list of GeoTrap shape nodes, build them all, 
+//! and store their pointers
+void ReadGeoModel::buildAllShapes_Trap()
+{
+    // create a builder and reserve size of memory map
+    size_t nSize = m_shapes_Trap.size();
+    m_builderShape_Trap = new BuildGeoShapes_Trap(nSize);
+    // loop over the DB rows and build the shapes
+    for (const auto &row : m_shapes_Trap)
+    {
+        // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG
+        m_builderShape_Trap->buildShape(row);
+    }
+    m_builderShape_Trap->printBuiltShapes(); // DEBUG MSG
+    if (nSize > 0) {
+        std::cout << "All " << nSize << " Shapes-Trap have been built!\n";
+    }
+}
+//! Iterate over the list of GeoTrd shape nodes, build them all, 
+//! and store their pointers
+void ReadGeoModel::buildAllShapes_Trd()
+{
+    // create a builder and reserve size of memory map
+    size_t nSize = m_shapes_Trd.size();
+    m_builderShape_Trd = new BuildGeoShapes_Trd(nSize);
+    // loop over the DB rows and build the shapes
+    for (const auto &row : m_shapes_Trd)
+    {
+        // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG
+        m_builderShape_Trd->buildShape(row);
+    }
+    m_builderShape_Trd->printBuiltShapes(); // DEBUG MSG
+    if (nSize > 0) {
+        std::cout << "All " << nSize << " Shapes-Trd have been built!\n";
+    }
+}
+//! Iterate over the list of GeoTubs shape nodes, build them all, 
+//! and store their pointers
+void ReadGeoModel::buildAllShapes_Tubs()
+{
+    // create a builder and reserve size of memory map
+    size_t nSize = m_shapes_Tubs.size();
+    m_builderShape_Tubs = new BuildGeoShapes_Tubs(nSize);
+    // loop over the DB rows and build the shapes
+    for (const auto &row : m_shapes_Tubs)
+    {
+        // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG
+        m_builderShape_Tubs->buildShape(row);
+    }
+    m_builderShape_Tubs->printBuiltShapes(); // DEBUG MSG
+    if (nSize > 0) {
+        std::cout << "All " << nSize << " Shapes-Tubs have been built!\n";
+    }
+}
+//! Iterate over the list of GeoTwistedTrap shape nodes, build them all, 
+//! and store their pointers
+void ReadGeoModel::buildAllShapes_TwistedTrap()
+{
+    // create a builder and reserve size of memory map
+    size_t nSize = m_shapes_TwistedTrap.size();
+    m_builderShape_TwistedTrap = new BuildGeoShapes_TwistedTrap(nSize);
+    // loop over the DB rows and build the shapes
+    for (const auto &row : m_shapes_TwistedTrap)
+    {
+        // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG
+        m_builderShape_TwistedTrap->buildShape(row);
+    }
+    m_builderShape_TwistedTrap->printBuiltShapes(); // DEBUG MSG
+    if (nSize > 0) {
+        std::cout << "All " << nSize << " Shapes-TwistedTrap have been built!\n";
+    }
+}
+//! Iterate over the list of GeoPcon shape nodes, build them all, 
+//! and store their pointers
 void ReadGeoModel::buildAllShapes_Pcon()
 {
     // create a builder and reserve size of memory map
@@ -574,8 +686,8 @@ void ReadGeoModel::buildAllShapes_Pcon()
         std::cout << "All " << nSize << " Shapes-Pcon have been built!\n";
     }
 }
-//! Iterate over the list of GeoPgon shapes, build them all, and store their
-//! pointers
+//! Iterate over the list of GeoPgon shape nodes, build them all, 
+//! and store their pointers
 void ReadGeoModel::buildAllShapes_Pgon()
 {
     // create a builder and reserve size of memory map
@@ -592,6 +704,24 @@ void ReadGeoModel::buildAllShapes_Pgon()
         std::cout << "All " << nSize << " Shapes-Pgon have been built!\n";
     }
 }
+//! Iterate over the list of GeoSimplePolygonBrep shape nodes, build them all, 
+//! and store their pointers
+void ReadGeoModel::buildAllShapes_SimplePolygonBrep()
+{
+    // create a builder and reserve size of memory map
+    size_t nSize = m_shapes_SimplePolygonBrep.size();
+    m_builderShape_SimplePolygonBrep = new BuildGeoShapes_SimplePolygonBrep(nSize, m_shapes_SimplePolygonBrep_data);
+    // loop over the DB rows and build the shapes
+    for (const auto &row : m_shapes_SimplePolygonBrep)
+    {
+        // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG
+        m_builderShape_SimplePolygonBrep->buildShape(row);
+    }
+    m_builderShape_SimplePolygonBrep->printBuiltShapes(); // DEBUG MSG
+    if (nSize > 0) {
+        std::cout << "All " << nSize << " Shapes-SimplePolygonBrep have been built!\n";
+    }
+}
 
 //! Iterate over the list of GeoSerialDenominator nodes, build them all, and
 //! store their pointers
@@ -1740,128 +1870,128 @@ GeoShape* ReadGeoModel::buildShape(const unsigned int shapeId,
 
         // shape = pcon;
     // } 
-    else if (type == "Pgon") {
-        // shape parameters
-        double SPhi = 0.;
-        double DPhi = 0.;
-        unsigned int NSides = 0;
-        unsigned int NZPlanes = 0;
-
-        bool error = false;
-        GeoPgon* pgon = nullptr;
-
-        std::string par;
-        std::vector<std::string> vars;
-        std::string varName;
-        std::string varValue;
-
-        int sizePars = shapePars.size();
-        // check if we have more than 3 parameters
-        if (sizePars > 3) {
-            // get the first four GeoPgon parameters: the SPhi and DPhi angles,
-            // plus the number of Z planes
-            for (int it = 0; it < 4; it++) {
-                par = shapePars[it];
-                vars = splitString(par, '=');
-                varName = vars[0];
-                varValue = vars[1];
-                // qInfo() << "vars: " << vars; // for debug only
-                if (varName == "SPhi") SPhi = std::stod(varValue);
-                if (varName == "DPhi") DPhi = std::stod(varValue);
-                if (varName == "NSides") NSides = std::stoi(varValue);
-                if (varName == "NZPlanes") NZPlanes = std::stoi(varValue);
-            }
-            // build the basic GeoPgon shape
-            pgon = new GeoPgon(SPhi, DPhi, NSides);
-
-            // and now loop over the rest of the list, to get the parameters of
-            // all Z planes
-            for (int it = 4; it < sizePars; it++) {
-                par = shapePars[it];
-                vars = splitString(par, '=');
-                varName = vars[0];
-                varValue = vars[1];
-
-                if (varName == "ZPos") {
-                    double zpos = std::stod(varValue);
-                    double rmin = 0., rmax = 0.;
-
-                    it++;  // go to next variable
-
-                    par = shapePars[it];
-                    vars = splitString(par, '=');
-                    varName = vars[0];
-                    varValue = vars[1];
-                    if (varName == "ZRmin")
-                        rmin = std::stod(varValue);
-                    else
-                        error = 1;
-                    it++;  // go to next variable
-
-                    par = shapePars[it];
-                    vars = splitString(par, '=');
-                    varName = vars[0];
-                    varValue = vars[1];
-                    if (varName == "ZRmax")
-                        rmax = std::stod(varValue);
-                    else
-                        error = 1;
-
-                    if (error) {
-                        muxCout.lock();
-                        std::cout << "ERROR! GeoPgon 'ZRmin' and 'ZRmax' "
-                                     "values are not at the right place! --> ";
-                        printStdVectorStrings(shapePars);
-                        muxCout.unlock();
-                    }
-
-                    // add a Z plane to the GeoPgon
-                    pgon->addPlane(zpos, rmin, rmax);
-                } else {
-                    error = 1;
-                    muxCout.lock();
-                    std::cout << "ERROR! GeoPgon 'ZPos' value is not at the "
-                                 "right place! --> ";
-                    printStdVectorStrings(shapePars);
-                    muxCout.unlock();
-                }
-            }
-
-            // sanity check on the resulting Pgon shape
-            if (pgon->getNPlanes() != NZPlanes) {
-                error = 1;
-                muxCout.lock();
-                std::cout << "ERROR! GeoPgon number of planes: "
-                          << pgon->getNPlanes()
-                          << " is not equal to the original size! --> ";
-                printStdVectorStrings(shapePars);
-                muxCout.unlock();
-            }
-            if (!pgon->isValid()) {
-                error = 1;
-                muxCout.lock();
-                std::cout << "ERROR! GeoPgon shape is not valid!! -- input: ";
-                printStdVectorStrings(shapePars);
-                muxCout.unlock();
-            }
-        }  // end if (size>3)
-        else {
-            muxCout.lock();
-            std::cout << "ERROR!! GeoPgon has no Z planes!! --> shape input "
-                         "parameters: ";
-            printStdVectorStrings(shapePars);
-            muxCout.unlock();
-            error = 1;
-        }
-        if (error) {
-            muxCout.lock();
-            std::cout << "FATAL ERROR!!! - GeoPgon shape error!!! Aborting..."
-                      << std::endl;
-            muxCout.unlock();
-            exit(EXIT_FAILURE);
-        }
-        shape = pgon;
-    } 
+    // else if (type == "Pgon") {
+    //     // shape parameters
+    //     double SPhi = 0.;
+    //     double DPhi = 0.;
+    //     unsigned int NSides = 0;
+    //     unsigned int NZPlanes = 0;
+
+    //     bool error = false;
+    //     GeoPgon* pgon = nullptr;
+
+    //     std::string par;
+    //     std::vector<std::string> vars;
+    //     std::string varName;
+    //     std::string varValue;
+
+    //     int sizePars = shapePars.size();
+    //     // check if we have more than 3 parameters
+    //     if (sizePars > 3) {
+    //         // get the first four GeoPgon parameters: the SPhi and DPhi angles,
+    //         // plus the number of Z planes
+    //         for (int it = 0; it < 4; it++) {
+    //             par = shapePars[it];
+    //             vars = splitString(par, '=');
+    //             varName = vars[0];
+    //             varValue = vars[1];
+    //             // qInfo() << "vars: " << vars; // for debug only
+    //             if (varName == "SPhi") SPhi = std::stod(varValue);
+    //             if (varName == "DPhi") DPhi = std::stod(varValue);
+    //             if (varName == "NSides") NSides = std::stoi(varValue);
+    //             if (varName == "NZPlanes") NZPlanes = std::stoi(varValue);
+    //         }
+    //         // build the basic GeoPgon shape
+    //         pgon = new GeoPgon(SPhi, DPhi, NSides);
+
+    //         // and now loop over the rest of the list, to get the parameters of
+    //         // all Z planes
+    //         for (int it = 4; it < sizePars; it++) {
+    //             par = shapePars[it];
+    //             vars = splitString(par, '=');
+    //             varName = vars[0];
+    //             varValue = vars[1];
+
+    //             if (varName == "ZPos") {
+    //                 double zpos = std::stod(varValue);
+    //                 double rmin = 0., rmax = 0.;
+
+    //                 it++;  // go to next variable
+
+    //                 par = shapePars[it];
+    //                 vars = splitString(par, '=');
+    //                 varName = vars[0];
+    //                 varValue = vars[1];
+    //                 if (varName == "ZRmin")
+    //                     rmin = std::stod(varValue);
+    //                 else
+    //                     error = 1;
+    //                 it++;  // go to next variable
+
+    //                 par = shapePars[it];
+    //                 vars = splitString(par, '=');
+    //                 varName = vars[0];
+    //                 varValue = vars[1];
+    //                 if (varName == "ZRmax")
+    //                     rmax = std::stod(varValue);
+    //                 else
+    //                     error = 1;
+
+    //                 if (error) {
+    //                     muxCout.lock();
+    //                     std::cout << "ERROR! GeoPgon 'ZRmin' and 'ZRmax' "
+    //                                  "values are not at the right place! --> ";
+    //                     printStdVectorStrings(shapePars);
+    //                     muxCout.unlock();
+    //                 }
+
+    //                 // add a Z plane to the GeoPgon
+    //                 pgon->addPlane(zpos, rmin, rmax);
+    //             } else {
+    //                 error = 1;
+    //                 muxCout.lock();
+    //                 std::cout << "ERROR! GeoPgon 'ZPos' value is not at the "
+    //                              "right place! --> ";
+    //                 printStdVectorStrings(shapePars);
+    //                 muxCout.unlock();
+    //             }
+    //         }
+
+    //         // sanity check on the resulting Pgon shape
+    //         if (pgon->getNPlanes() != NZPlanes) {
+    //             error = 1;
+    //             muxCout.lock();
+    //             std::cout << "ERROR! GeoPgon number of planes: "
+    //                       << pgon->getNPlanes()
+    //                       << " is not equal to the original size! --> ";
+    //             printStdVectorStrings(shapePars);
+    //             muxCout.unlock();
+    //         }
+    //         if (!pgon->isValid()) {
+    //             error = 1;
+    //             muxCout.lock();
+    //             std::cout << "ERROR! GeoPgon shape is not valid!! -- input: ";
+    //             printStdVectorStrings(shapePars);
+    //             muxCout.unlock();
+    //         }
+    //     }  // end if (size>3)
+    //     else {
+    //         muxCout.lock();
+    //         std::cout << "ERROR!! GeoPgon has no Z planes!! --> shape input "
+    //                      "parameters: ";
+    //         printStdVectorStrings(shapePars);
+    //         muxCout.unlock();
+    //         error = 1;
+    //     }
+    //     if (error) {
+    //         muxCout.lock();
+    //         std::cout << "FATAL ERROR!!! - GeoPgon shape error!!! Aborting..."
+    //                   << std::endl;
+    //         muxCout.unlock();
+    //         exit(EXIT_FAILURE);
+    //     }
+    //     shape = pgon;
+    // } 
     else if (type == "GenericTrap") {
         // shape parameters
         double ZHalfLength = 0.;
@@ -1957,114 +2087,115 @@ GeoShape* ReadGeoModel::buildShape(const unsigned int shapeId,
             exit(EXIT_FAILURE);
         }
         shape = gTrap;
-    } else if (type == "SimplePolygonBrep") {
-        // shape parameters
-        double DZ = 0.;
-        unsigned int NVertices = 0;
-        double xV = 0.;
-        double yV = 0.;
-
-        bool error = 0;
-        GeoSimplePolygonBrep* sh = nullptr;
-
-        std::string par;
-        std::vector<std::string> vars;
-        std::string varName;
-        std::string varValue;
-
-        int sizePars = shapePars.size();
-        // check if we have more than 2 parameters
-        if (sizePars > 2) {
-            // get the first two GeoSimplePolygonBrep parameters: DZ and the
-            // number of vertices.
-            for (int it = 0; it < 2; it++) {
-                par = shapePars[it];
-                vars = splitString(par, '=');
-                varName = vars[0];
-                varValue = vars[1];
-                if (varName == "DZ") DZ = std::stod(varValue);
-                if (varName == "NVertices") NVertices = std::stoi(varValue);
-                // else if (varName == "NVertices") NVertices =
-                // varValue.toDouble(); else error = 1; if(error) std::cout <<
-                // "ERROR! GeoSimplePolygonBrep parameters are not correctly
-                // stored! -->" << vars;
-            }
-            // build the basic GeoSimplePolygonBrep shape
-            sh = new GeoSimplePolygonBrep(DZ);
-
-            // and now loop over the rest of the list, to get the parameters of
-            // all vertices
-            for (int it = 2; it < sizePars; it++) {
-                par = shapePars[it];
-                vars = splitString(par, '=');
-                varName = vars[0];
-                varValue = vars[1];
-                if (varName == "xV")
-                    xV = std::stod(varValue);
-                else
-                    error = 1;
-
-                it++;  // go to next variable (they come in pairs)
-
-                par = shapePars[it];
-                vars = splitString(par, '=');
-                varName = vars[0];
-                varValue = vars[1];
-                if (varName == "yV")
-                    yV = std::stod(varValue);
-                else
-                    error = 1;
-
-                if (error) {
-                    muxCout.lock();
-                    std::cout << "ERROR! GeoSimplePolygonBrep 'xVertex' and "
-                                 "'yVertex' values are not at the right place! "
-                                 "--> ";
-                    printStdVectorStrings(shapePars);
-                    muxCout.unlock();
-                }
-
-                // add a Z plane to the GeoSimplePolygonBrep
-                sh->addVertex(xV, yV);
-            }
-            // sanity check on the resulting shape
-            if (sh->getNVertices() != NVertices) {
-                error = 1;
-                muxCout.lock();
-                std::cout << "ERROR! GeoSimplePolygonBrep number of planes: "
-                          << sh->getNVertices()
-                          << " is not equal to the original size! --> ";
-                printStdVectorStrings(shapePars);
-                muxCout.unlock();
-            }
-            if (!sh->isValid()) {
-                error = 1;
-                muxCout.lock();
-                std::cout << "ERROR! GeoSimplePolygonBrep shape is not valid!! "
-                             "-- input: ";
-                printStdVectorStrings(shapePars);
-                muxCout.unlock();
-            }
-        }  // end if (size>3)
-        else {
-            muxCout.lock();
-            std::cout << "ERROR!! GeoSimplePolygonBrep has no vertices!! --> "
-                         "shape input parameters: ";
-            printStdVectorStrings(shapePars);
-            muxCout.unlock();
-            error = 1;
-        }
-        if (error) {
-            muxCout.lock();
-            std::cout << "FATAL ERROR!!! - GeoSimplePolygonBrep shape error!!! "
-                         "Aborting..."
-                      << std::endl;
-            muxCout.unlock();
-            exit(EXIT_FAILURE);
-        }
-        shape = sh;
-
-    } else if (type == "TessellatedSolid") {
+    } 
+    // else if (type == "SimplePolygonBrep") {
+    //     // shape parameters
+    //     double DZ = 0.;
+    //     unsigned int NVertices = 0;
+    //     double xV = 0.;
+    //     double yV = 0.;
+
+    //     bool error = 0;
+    //     GeoSimplePolygonBrep* sh = nullptr;
+
+    //     std::string par;
+    //     std::vector<std::string> vars;
+    //     std::string varName;
+    //     std::string varValue;
+
+    //     int sizePars = shapePars.size();
+    //     // check if we have more than 2 parameters
+    //     if (sizePars > 2) {
+    //         // get the first two GeoSimplePolygonBrep parameters: DZ and the
+    //         // number of vertices.
+    //         for (int it = 0; it < 2; it++) {
+    //             par = shapePars[it];
+    //             vars = splitString(par, '=');
+    //             varName = vars[0];
+    //             varValue = vars[1];
+    //             if (varName == "DZ") DZ = std::stod(varValue);
+    //             if (varName == "NVertices") NVertices = std::stoi(varValue);
+    //             // else if (varName == "NVertices") NVertices =
+    //             // varValue.toDouble(); else error = 1; if(error) std::cout <<
+    //             // "ERROR! GeoSimplePolygonBrep parameters are not correctly
+    //             // stored! -->" << vars;
+    //         }
+    //         // build the basic GeoSimplePolygonBrep shape
+    //         sh = new GeoSimplePolygonBrep(DZ);
+
+    //         // and now loop over the rest of the list, to get the parameters of
+    //         // all vertices
+    //         for (int it = 2; it < sizePars; it++) {
+    //             par = shapePars[it];
+    //             vars = splitString(par, '=');
+    //             varName = vars[0];
+    //             varValue = vars[1];
+    //             if (varName == "xV")
+    //                 xV = std::stod(varValue);
+    //             else
+    //                 error = 1;
+
+    //             it++;  // go to next variable (they come in pairs)
+
+    //             par = shapePars[it];
+    //             vars = splitString(par, '=');
+    //             varName = vars[0];
+    //             varValue = vars[1];
+    //             if (varName == "yV")
+    //                 yV = std::stod(varValue);
+    //             else
+    //                 error = 1;
+
+    //             if (error) {
+    //                 muxCout.lock();
+    //                 std::cout << "ERROR! GeoSimplePolygonBrep 'xVertex' and "
+    //                              "'yVertex' values are not at the right place! "
+    //                              "--> ";
+    //                 printStdVectorStrings(shapePars);
+    //                 muxCout.unlock();
+    //             }
+
+    //             // add a Z plane to the GeoSimplePolygonBrep
+    //             sh->addVertex(xV, yV);
+    //         }
+    //         // sanity check on the resulting shape
+    //         if (sh->getNVertices() != NVertices) {
+    //             error = 1;
+    //             muxCout.lock();
+    //             std::cout << "ERROR! GeoSimplePolygonBrep number of planes: "
+    //                       << sh->getNVertices()
+    //                       << " is not equal to the original size! --> ";
+    //             printStdVectorStrings(shapePars);
+    //             muxCout.unlock();
+    //         }
+    //         if (!sh->isValid()) {
+    //             error = 1;
+    //             muxCout.lock();
+    //             std::cout << "ERROR! GeoSimplePolygonBrep shape is not valid!! "
+    //                          "-- input: ";
+    //             printStdVectorStrings(shapePars);
+    //             muxCout.unlock();
+    //         }
+    //     }  // end if (size>3)
+    //     else {
+    //         muxCout.lock();
+    //         std::cout << "ERROR!! GeoSimplePolygonBrep has no vertices!! --> "
+    //                      "shape input parameters: ";
+    //         printStdVectorStrings(shapePars);
+    //         muxCout.unlock();
+    //         error = 1;
+    //     }
+    //     if (error) {
+    //         muxCout.lock();
+    //         std::cout << "FATAL ERROR!!! - GeoSimplePolygonBrep shape error!!! "
+    //                      "Aborting..."
+    //                   << std::endl;
+    //         muxCout.unlock();
+    //         exit(EXIT_FAILURE);
+    //     }
+    //     shape = sh;
+    // } 
+    else if (type == "TessellatedSolid") {
         // Tessellated pars example:
         // "nFacets=1;TRI;vT=ABSOLUTE;nV=3;xV=0;yV=0;zV=1;xV=0;yV=1;zV=0;xV=1;yV=0;zV=0"
         std::cout << "Reading-in: TessellatedSolid: ";  // debug
@@ -2361,50 +2492,52 @@ GeoShape* ReadGeoModel::buildShape(const unsigned int shapeId,
         }
         shape = sh;
 
-    } else if (type == "Trap") {
-        // shape constructor parameters
-        double ZHalfLength = 0.;
-        double Theta = 0.;
-        double Phi = 0.;
-        double Dydzn = 0.;
-        double Dxdyndzn = 0.;
-        double Dxdypdzn = 0.;
-        double Angleydzn = 0.;
-        double Dydzp = 0.;
-        double Dxdyndzp = 0.;
-        double Dxdypdzp = 0.;
-        double Angleydzp = 0.;
-        // get parameters
-        for (auto& par : shapePars) {
-            std::vector<std::string> vars = splitString(par, '=');
-            std::string varName = vars[0];
-            std::string varValue = vars[1];
-            if (varName == "ZHalfLength")
-                ZHalfLength = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Theta")
-                Theta = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Phi")
-                Phi = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Dydzn")
-                Dydzn = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Dxdyndzn")
-                Dxdyndzn = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Dxdypdzn")
-                Dxdypdzn = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Angleydzn")
-                Angleydzn = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Dydzp")
-                Dydzp = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Dxdyndzp")
-                Dxdyndzp = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Dxdypdzp")
-                Dxdypdzp = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "Angleydzp")
-                Angleydzp = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-        }
-        shape = new GeoTrap(ZHalfLength, Theta, Phi, Dydzn, Dxdyndzn, Dxdypdzn,
-                            Angleydzn, Dydzp, Dxdyndzp, Dxdypdzp, Angleydzp);
-    } else if (type == "TwistedTrap") {
+    } 
+    // else if (type == "Trap") {
+        // // shape constructor parameters
+        // double ZHalfLength = 0.;
+        // double Theta = 0.;
+        // double Phi = 0.;
+        // double Dydzn = 0.;
+        // double Dxdyndzn = 0.;
+        // double Dxdypdzn = 0.;
+        // double Angleydzn = 0.;
+        // double Dydzp = 0.;
+        // double Dxdyndzp = 0.;
+        // double Dxdypdzp = 0.;
+        // double Angleydzp = 0.;
+        // // get parameters
+        // for (auto& par : shapePars) {
+        //     std::vector<std::string> vars = splitString(par, '=');
+        //     std::string varName = vars[0];
+        //     std::string varValue = vars[1];
+        //     if (varName == "ZHalfLength")
+        //         ZHalfLength = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Theta")
+        //         Theta = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Phi")
+        //         Phi = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Dydzn")
+        //         Dydzn = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Dxdyndzn")
+        //         Dxdyndzn = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Dxdypdzn")
+        //         Dxdypdzn = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Angleydzn")
+        //         Angleydzn = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Dydzp")
+        //         Dydzp = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Dxdyndzp")
+        //         Dxdyndzp = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Dxdypdzp")
+        //         Dxdypdzp = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "Angleydzp")
+        //         Angleydzp = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        // }
+        // shape = new GeoTrap(ZHalfLength, Theta, Phi, Dydzn, Dxdyndzn, Dxdypdzn,
+        //                     Angleydzn, Dydzp, Dxdyndzp, Dxdypdzp, Angleydzp);
+    // } 
+    else if (type == "TwistedTrap") {
         // shape constructor parameters
         double PhiTwist = 0;
         double ZHalfLength = 0.;
@@ -2446,75 +2579,79 @@ GeoShape* ReadGeoModel::buildShape(const unsigned int shapeId,
             new GeoTwistedTrap(PhiTwist, ZHalfLength, Theta, Phi, DY1HalfLength,
                                DX1HalfLength, DX2HalfLength, DY2HalfLength,
                                DX3HalfLength, DX4HalfLength, DTiltAngleAlpha);
-    } else if (type == "Trd") {
+    } 
+    // else if (type == "Trd") {
         // shape constructor parameters
-        double XHalfLength1 = 0.;
-        double XHalfLength2 = 0.;
-        double YHalfLength1 = 0.;
-        double YHalfLength2 = 0.;
-        double ZHalfLength = 0.;
-        // get parameters
-        for (auto& par : shapePars) {
-            std::vector<std::string> vars = splitString(par, '=');
-            std::string varName = vars[0];
-            std::string varValue = vars[1];
-            // std::cout << "varValue:" << varValue;
-            if (varName == "XHalfLength1")
-                XHalfLength1 = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "XHalfLength2")
-                XHalfLength2 = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "YHalfLength1")
-                YHalfLength1 = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "YHalfLength2")
-                YHalfLength2 = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "ZHalfLength")
-                ZHalfLength = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-        }
-        shape = new GeoTrd(XHalfLength1, XHalfLength2, YHalfLength1,
-                           YHalfLength2, ZHalfLength);
-    } else if (type == "Tube") {
-        // shape parameters
-        double RMin = 0.;
-        double RMax = 0.;
-        double ZHalfLength = 0.;
-        // get parameters
-        for (auto& par : shapePars) {
-            std::vector<std::string> vars = splitString(par, '=');
-            std::string varName = vars[0];
-            std::string varValue = vars[1];
-            if (varName == "RMin")
-                RMin = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "RMax")
-                RMax = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "ZHalfLength")
-                ZHalfLength = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-        }
-        shape = new GeoTube(RMin, RMax, ZHalfLength);
-    } else if (type == "Tubs") {
-        // shape parameters
-        double RMin = 0.;
-        double RMax = 0.;
-        double ZHalfLength = 0.;
-        double SPhi = 0.;
-        double DPhi = 0.;
-        // get parameters
-        for (auto& par : shapePars) {
-            std::vector<std::string> vars = splitString(par, '=');
-            std::string varName = vars[0];
-            std::string varValue = vars[1];
-            if (varName == "RMin")
-                RMin = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "RMax")
-                RMax = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "ZHalfLength")
-                ZHalfLength = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "SPhi")
-                SPhi = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-            if (varName == "DPhi")
-                DPhi = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
-        }
-        shape = new GeoTubs(RMin, RMax, ZHalfLength, SPhi, DPhi);
-    } else if (type == "Shift") {
+        // double XHalfLength1 = 0.;
+        // double XHalfLength2 = 0.;
+        // double YHalfLength1 = 0.;
+        // double YHalfLength2 = 0.;
+        // double ZHalfLength = 0.;
+        // // get parameters
+        // for (auto& par : shapePars) {
+        //     std::vector<std::string> vars = splitString(par, '=');
+        //     std::string varName = vars[0];
+        //     std::string varValue = vars[1];
+        //     // std::cout << "varValue:" << varValue;
+        //     if (varName == "XHalfLength1")
+        //         XHalfLength1 = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "XHalfLength2")
+        //         XHalfLength2 = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "YHalfLength1")
+        //         YHalfLength1 = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "YHalfLength2")
+        //         YHalfLength2 = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "ZHalfLength")
+        //         ZHalfLength = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        // }
+        // shape = new GeoTrd(XHalfLength1, XHalfLength2, YHalfLength1,
+        //                    YHalfLength2, ZHalfLength);
+    // } 
+    // else if (type == "Tube") {
+    //     // shape parameters
+    //     double RMin = 0.;
+    //     double RMax = 0.;
+    //     double ZHalfLength = 0.;
+    //     // get parameters
+    //     for (auto& par : shapePars) {
+    //         std::vector<std::string> vars = splitString(par, '=');
+    //         std::string varName = vars[0];
+    //         std::string varValue = vars[1];
+    //         if (varName == "RMin")
+    //             RMin = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+    //         if (varName == "RMax")
+    //             RMax = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+    //         if (varName == "ZHalfLength")
+    //             ZHalfLength = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+    //     }
+    //     shape = new GeoTube(RMin, RMax, ZHalfLength);
+    // } 
+    // else if (type == "Tubs") {
+        // // shape parameters
+        // double RMin = 0.;
+        // double RMax = 0.;
+        // double ZHalfLength = 0.;
+        // double SPhi = 0.;
+        // double DPhi = 0.;
+        // // get parameters
+        // for (auto& par : shapePars) {
+        //     std::vector<std::string> vars = splitString(par, '=');
+        //     std::string varName = vars[0];
+        //     std::string varValue = vars[1];
+        //     if (varName == "RMin")
+        //         RMin = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "RMax")
+        //         RMax = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "ZHalfLength")
+        //         ZHalfLength = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "SPhi")
+        //         SPhi = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        //     if (varName == "DPhi")
+        //         DPhi = std::stod(varValue);  // * SYSTEM_OF_UNITS::mm;
+        // }
+        // shape = new GeoTubs(RMin, RMax, ZHalfLength, SPhi, DPhi);
+    // } 
+    else if (type == "Shift") {
         // shape parameters
         unsigned int shapeOpId = 0;
         unsigned int transfId = 0;
@@ -3198,7 +3335,7 @@ GeoLogVol* ReadGeoModel::buildLogVol(const unsigned int id) {
     const std::string shapeType = GeoModelHelpers::variantHelper::getFromVariant_String(values[3], "LogVol_shapeType");
     GeoShape* shape = getBuiltShape(shapeId, shapeType);
     if (!shape) {
-            THROW_EXCEPTION("ERROR!! While building a LogVol, Shape of type '" + shapeType + "' is NULL! Exiting...");
+            THROW_EXCEPTION("ERROR!! While building the LogVol '" + logVolName + "', shape of type '" + shapeType + "' is NULL! Exiting...");
     }
 
     // build the referenced GeoMaterial node
@@ -3212,7 +3349,7 @@ GeoLogVol* ReadGeoModel::buildLogVol(const unsigned int id) {
     }
     GeoMaterial* mat = getBuiltMaterial(matId);
     if (!mat) {
-            THROW_EXCEPTION("ERROR!! While building a LogVol, Material of ID '" + std::to_string(matId) + "' is NULL! Exiting...");
+            THROW_EXCEPTION("ERROR!! While building the LogVol '" + logVolName + "', Material of ID '" + std::to_string(matId) + "' is NULL! Exiting...");
     }
 
     GeoLogVol* logPtr = new GeoLogVol(logVolName, shape, mat);
@@ -3455,7 +3592,7 @@ void ReadGeoModel::storeBuiltShape(const unsigned int id, GeoShape* nodePtr) {
 GeoShape *ReadGeoModel::getBuiltShape(const unsigned int shapeId, std::string_view shapeType)
 {
 
-    const std::set<std::string> shapesNewDB{"Box", "Tube", "Pcon", "Cons", "Para", "Pgon"};
+    const std::set<std::string> shapesNewDB{"Box", "Tube", "Pcon", "Cons", "Para", "Pgon", "Trap", "Trd", "Tubs", "TwistedTrap", "SimplePolygonBrep"};
     // get shape parameters
     if (std::count(shapesNewDB.begin(), shapesNewDB.end(), shapeType))
     {
@@ -3483,6 +3620,26 @@ GeoShape *ReadGeoModel::getBuiltShape(const unsigned int shapeId, std::string_vi
         {
             return m_builderShape_Pgon->getBuiltShape(shapeId);
         } 
+        else if ("Trap" == shapeType)
+        {
+            return m_builderShape_Trap->getBuiltShape(shapeId);
+        } 
+        else if ("Trd" == shapeType)
+        {
+            return m_builderShape_Trd->getBuiltShape(shapeId);
+        } 
+        else if ("Tubs" == shapeType)
+        {
+            return m_builderShape_Tubs->getBuiltShape(shapeId);
+        } 
+        else if ("TwistedTrap" == shapeType)
+        {
+            return m_builderShape_TwistedTrap->getBuiltShape(shapeId);
+        } 
+        else if ("SimplePolygonBrep" == shapeType)
+        {
+            return m_builderShape_SimplePolygonBrep->getBuiltShape(shapeId);
+        } 
         else {
             THROW_EXCEPTION("ERROR!!! Shape '" + std::string(shapeType) + "' is not handled correctly!");
         }
diff --git a/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h b/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
index 7f8231b62..584e8234e 100644
--- a/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
+++ b/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
@@ -27,6 +27,8 @@
 
 // local includes
 #include "GeoModelDBManager/GMDBManager.h"
+#include "GeoModelDBManager/definitions.h"
+
 
 // GeoModel includes
 #include "GeoModelKernel/GeoAlignableTransform.h"
@@ -215,12 +217,12 @@ class WriteGeoModel : public GeoNodeAction {
 
     unsigned int addRecord(std::vector<std::vector<std::string>> *container,
                            const std::vector<std::string> values) const;
-    unsigned int addRecord(std::vector<std::vector<std::variant<int, long, float, double, std::string>>> *container,
+    unsigned int addRecord(DBRowsList *container,
                            const std::vector<std::variant<int, long, float, double, std::string>> values) const;
     
     std::pair<unsigned, unsigned> addRecordData(
-        std::vector<std::vector<std::variant<int, long, float, double, std::string>>> *container,
-        const std::vector<std::vector<std::variant<int, long, float, double, std::string>>> values) const;
+        DBRowsList *container,
+        const DBRowsList values) const;
 
     unsigned int addMaterial(const std::string &name, const double &density,
                              const std::string &elements);
@@ -239,7 +241,7 @@ class WriteGeoModel : public GeoNodeAction {
     unsigned int addShape(const std::string &type,
                           const std::vector<std::variant<int, long, float, double, std::string>> &parameters);
     std::pair<unsigned, unsigned> addShapeData(const std::string type,
-                                       const std::vector<std::vector<std::variant<int, long, float, double, std::string>>> &shapeData);
+                                       const DBRowsList &shapeData);
     unsigned int addSerialDenominator(const std::string &baseName);
     unsigned int addSerialIdentifier(const int &baseId);
     unsigned int addIdentifierTag(const int &identifier);
@@ -305,7 +307,7 @@ class WriteGeoModel : public GeoNodeAction {
                                // from TransFunctionRecorder as well.
     std::string getShapeParameters(const GeoShape *);
     std::pair<std::vector<std::variant<int, long, float, double, std::string>>,
-              std::vector<std::vector<std::variant<int, long, float, double, std::string>>>>
+              DBRowsList>
     getShapeParametersV(const GeoShape *, const bool data = false);
 
     std::string getGeoTypeFromVPhysVol(const GeoVPhysVol *vol);
@@ -342,7 +344,7 @@ class WriteGeoModel : public GeoNodeAction {
     bool m_unconnectedTree;
 
     // chaches in the new DB schema
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_logVols;
+    DBRowsList m_logVols;
 
     // caches for GeoModel nodes to be saved into the DB
     // std::vector<std::vector<std::string>> m_logVols;
@@ -358,21 +360,25 @@ class WriteGeoModel : public GeoNodeAction {
     std::vector<std::vector<std::string>> m_serialTransformers;
     std::vector<std::vector<std::string>> m_nameTags;
     std::vector<std::vector<std::string>> m_shapes;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Box;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Tube;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Cons;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Para;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Pcon;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Pgon;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Trap;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Trd;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Tubs;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_TwistedTrap;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Pcon_Data;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Pgon_Data;
+
+    DBRowsList m_shapes_Box;
+    DBRowsList m_shapes_Tube;
+    DBRowsList m_shapes_Cons;
+    DBRowsList m_shapes_Para;
+    DBRowsList m_shapes_Trap;
+    DBRowsList m_shapes_Trd;
+    DBRowsList m_shapes_Tubs;
+    DBRowsList m_shapes_TwistedTrap;
+
+    DBRowsList m_shapes_Pcon;
+    DBRowsList m_shapes_Pgon;
+    DBRowsList m_shapes_SimplePolygonBrep;
+    DBRowsList m_shapes_Pcon_Data;
+    DBRowsList m_shapes_Pgon_Data;
+    DBRowsList m_shapes_SimplePolygonBrep_Data;
 
     // std::vector<std::vector<std::string>> m_functions;
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_functions; // operators used in Function's expression
+    DBRowsList m_functions; // operators used in Function's expression
 
     // caches for additional data to be saved into the DB
     std::vector<std::variant<int, long, float, double, std::string>> m_exprData; // numbers used in Function's expression
diff --git a/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp b/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp
index 3dbb8d6ed..36b364113 100644
--- a/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp
+++ b/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp
@@ -700,7 +700,7 @@ unsigned int WriteGeoModel::storeShape(const GeoShape* shape) {
     // LArCustomShape is deprecated.  Write it out as a GeoUnidentifiedShape;
     if (shapeType == "CustomShape") shapeType = "UnidentifiedShape";
 
-    const std::set<std::string> shapesNewDB{"Box", "Tube", "Cons", "Para", "Trap", "Trd", "Tubs", "TwistedTrap", "Pcon", "Pgon"};
+    const std::set<std::string> shapesNewDB{"Box", "Tube", "Cons", "Para", "Trap", "Trd", "Tubs", "TwistedTrap", "Pcon", "Pgon", "SimplePolygonBrep"};
 
     // get shape parameters
     if (std::count(shapesNewDB.begin(), shapesNewDB.end(), shapeType))
@@ -1083,6 +1083,7 @@ WriteGeoModel::getShapeParametersV(const GeoShape *shape, const bool data)
         const GeoPgon* shapeIn = dynamic_cast<const GeoPgon*>(shape);
         shapePars.push_back(shapeIn->getSPhi());
         shapePars.push_back(shapeIn->getDPhi());
+        shapePars.push_back(shapeIn->getNSides());
         // get number of Z planes and loop over them
         const int nZplanes = shapeIn->getNPlanes();
         shapePars.push_back(nZplanes);
@@ -1094,6 +1095,20 @@ WriteGeoModel::getShapeParametersV(const GeoShape *shape, const bool data)
             dataRow.clear();
         }
     }
+    else if (shapeType == "SimplePolygonBrep")
+    {
+        const GeoSimplePolygonBrep* shapeIn = dynamic_cast<const GeoSimplePolygonBrep*>(shape);
+        shapePars.push_back(shapeIn->getDZ());
+        // get number of Z planes and loop over them
+        const int nVertices = shapeIn->getNVertices();
+        shapePars.push_back(nVertices);
+        for (int i = 0; i < nVertices; ++i) {
+            dataRow.push_back(shapeIn->getXVertex(i));
+            dataRow.push_back(shapeIn->getYVertex(i));
+            shapeData.push_back(dataRow);
+            dataRow.clear();
+        }
+    }
     else
     {
         std::cout << "\n\tGeoModelWrite -- WARNING!!! - Shape '" << shapeType
@@ -1200,20 +1215,20 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape) {
     //                        CppHelper::to_string_with_precision(shapeIn->getRMaxPlane(i)));
     //     }
     // } 
-    else if (shapeType == "SimplePolygonBrep") {
-        const GeoSimplePolygonBrep* shapeIn =
-            dynamic_cast<const GeoSimplePolygonBrep*>(shape);
-        pars.push_back("DZ=" + CppHelper::to_string_with_precision(shapeIn->getDZ()));
-        // get number of vertices and loop over them
-        const int nVertices = shapeIn->getNVertices();
-        pars.push_back("NVertices=" + std::to_string(nVertices));  // INT
-        for (int i = 0; i < nVertices; ++i) {
-            pars.push_back("xV=" +
-                           CppHelper::to_string_with_precision(shapeIn->getXVertex(i)));
-            pars.push_back("yV=" +
-                           CppHelper::to_string_with_precision(shapeIn->getYVertex(i)));
-        }
-    } 
+    // else if (shapeType == "SimplePolygonBrep") {
+    //     const GeoSimplePolygonBrep* shapeIn =
+    //         dynamic_cast<const GeoSimplePolygonBrep*>(shape);
+    //     pars.push_back("DZ=" + CppHelper::to_string_with_precision(shapeIn->getDZ()));
+    //     // get number of vertices and loop over them
+    //     const int nVertices = shapeIn->getNVertices();
+    //     pars.push_back("NVertices=" + std::to_string(nVertices));  // INT
+    //     for (int i = 0; i < nVertices; ++i) {
+    //         pars.push_back("xV=" +
+    //                        CppHelper::to_string_with_precision(shapeIn->getXVertex(i)));
+    //         pars.push_back("yV=" +
+    //                        CppHelper::to_string_with_precision(shapeIn->getYVertex(i)));
+    //     }
+    // } 
     // else if (shapeType == "Trap") {
     //     const GeoTrap* shapeIn = dynamic_cast<const GeoTrap*>(shape);
     //     pars.push_back("ZHalfLength=" +
@@ -1878,16 +1893,20 @@ std::vector<unsigned> WriteGeoModel::addExprData(
 }
 
 std::pair<unsigned, unsigned> WriteGeoModel::addShapeData(const std::string type,
-    const std::vector<std::vector<std::variant<int, long, float, double, std::string>>>& shapeData) 
+    const DBRowsList& shapeData) 
 {
-    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> *container = nullptr;
+    DBRowsList *container = nullptr;
 
     if ("Pcon" == type) {
         container = &m_shapes_Pcon_Data;
     }
     else if ("Pgon" == type) {
         container = &m_shapes_Pgon_Data;
-    } else {
+    } 
+    else if ("SimplePolygonBrep" == type) {
+        container = &m_shapes_SimplePolygonBrep_Data;
+    } 
+    else {
         std::cout << "\nERROR!!! Shape data for shape '" << type << "' have not been set, yet!\n" << std::endl;
     }
     
@@ -2330,6 +2349,10 @@ unsigned int WriteGeoModel::addShape(const std::string &type,
     {
         container = &m_shapes_Pgon;
     }
+    else if ("SimplePolygonBrep" == type)
+    {
+        container = &m_shapes_SimplePolygonBrep;
+    }
     else
     {
         std::cout << "\nERROR! Shape type '" << type
@@ -2457,8 +2480,10 @@ void WriteGeoModel::saveToDB(std::vector<GeoPublisher*>& publishers) {
     // FIXME: To do this, I moved addListOfRecordsToTable() from private to public, maybe I could add a method to store shapes with data and put back that into private
     m_dbManager->addListOfRecords("GeoPcon", m_shapes_Pcon); // new version, with shape's parameters as numbers
     m_dbManager->addListOfRecords("GeoPgon", m_shapes_Pgon); // new version, with shape's parameters as numbers
+    m_dbManager->addListOfRecords("GeoSimplePolygonBrep", m_shapes_SimplePolygonBrep); // new version, with shape's parameters as numbers
     m_dbManager->addListOfRecordsToTable("Shapes_Pcon_Data", m_shapes_Pcon_Data); // new version, with shape's parameters as numbers
     m_dbManager->addListOfRecordsToTable("Shapes_Pgon_Data", m_shapes_Pgon_Data); // new version, with shape's parameters as numbers
+    m_dbManager->addListOfRecordsToTable("Shapes_SimplePolygonBrep_Data", m_shapes_SimplePolygonBrep_Data); // new version, with shape's parameters as numbers
 
     m_dbManager->addListOfChildrenPositions(m_childrenPositions);
     m_dbManager->addRootVolume(m_rootVolume);
-- 
GitLab