From 466bbe6c4cff67d2fdbe8b3cbc8f1e944f3f0b7b Mon Sep 17 00:00:00 2001
From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch>
Date: Fri, 31 May 2024 10:41:01 +0200
Subject: [PATCH] Start moving all nodes to the new DB schema

---
 .gitignore                                    |   1 +
 GeoModelCore/GeoModelKernel/src/GeoBox.cxx    |   2 +-
 GeoModelExamples/CMakeLists.txt               |  12 +-
 ...ep1_create_store_geo_and_publish_nodes.cpp |  22 +++
 .../GeoModelDBManager/GMDBManager.h           |  43 ++--
 .../GeoModelDBManager/src/GMDBManager.cpp     | 186 ++++++++++--------
 .../GeoModelRead/GeoModelRead/ReadGeoModel.h  |   9 +-
 .../GeoModelRead/ReadGeoModel.tpp             |  31 ++-
 GeoModelIO/GeoModelRead/src/NOTES_UPDATE.md   |  51 +++++
 GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp  |  22 ++-
 .../GeoModelWrite/WriteGeoModel.h             |   4 +-
 .../GeoModelWrite/src/WriteGeoModel.cpp       |  14 +-
 .../VP1GeometryPlugin/CMakeLists.txt          |   3 +-
 .../src/SoVisualizeAction.cxx                 |  18 +-
 .../src/VolumeHandleSharedData.cxx            |  45 +++--
 15 files changed, 300 insertions(+), 163 deletions(-)
 create mode 100644 GeoModelIO/GeoModelRead/src/NOTES_UPDATE.md

diff --git a/.gitignore b/.gitignore
index 8d99a9e3f..913334569 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@
 # VSCode-related files and folders
 build
 .vscode
+install
diff --git a/GeoModelCore/GeoModelKernel/src/GeoBox.cxx b/GeoModelCore/GeoModelKernel/src/GeoBox.cxx
index 60b44f062..209d007c6 100755
--- a/GeoModelCore/GeoModelKernel/src/GeoBox.cxx
+++ b/GeoModelCore/GeoModelKernel/src/GeoBox.cxx
@@ -6,7 +6,7 @@
 #include "GeoModelKernel/GeoShapeAction.h"
 
 const std::string GeoBox::s_classType = "Box";
-const ShapeType GeoBox::s_classTypeID = 0x10;
+const ShapeType GeoBox::s_classTypeID = 0x10; // 16
 
 GeoBox::GeoBox (double XHalfLength, double YHalfLength, double ZHalfLength):
   m_xHalfLength {XHalfLength},
diff --git a/GeoModelExamples/CMakeLists.txt b/GeoModelExamples/CMakeLists.txt
index b819e97a3..82ab2656d 100644
--- a/GeoModelExamples/CMakeLists.txt
+++ b/GeoModelExamples/CMakeLists.txt
@@ -15,13 +15,15 @@ add_subdirectory( MinimalPlugin )
 add_subdirectory( SurfaceTestPlugin )
 
 add_subdirectory( HelloGeo )
-add_subdirectory( HelloGeoWrite )
-add_subdirectory( HelloGeoWriteReadWrite )
-add_subdirectory( HelloGeoRead )
-add_subdirectory( HelloGeoReadNodeAction )
+# add_subdirectory( HelloGeoWrite )
+# add_subdirectory( HelloGeoWriteReadWrite )
+# add_subdirectory( HelloGeoRead )
+# add_subdirectory( HelloGeoReadNodeAction )
+# add_subdirectory( SharedNodes )
+add_subdirectory( HelloToyWrite )
 
 #add_subdirectory( HelloDummyMaterial )
-#add_subdirectory( HelloToy )
+add_subdirectory( HelloToy )
 #add_subdirectory( HelloToyDetectorFactory )
 #add_subdirectory( HelloToyXML ) # this should be moved to GeoModelATLAS, because it uses GeoModelDataManagers
 
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 bb24ad4c6..e78e377a8 100644
--- a/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp
+++ b/GeoModelExamples/HelloToy/step1_create_store_geo_and_publish_nodes.cpp
@@ -184,6 +184,7 @@ int main(int argc, char *argv[])
   //--------------------------------------//
 
   GeoBox       *sPass = new GeoBox(5.0*SYSTEM_OF_UNITS::cm, 30*SYSTEM_OF_UNITS::cm, 30*SYSTEM_OF_UNITS::cm);
+  // GeoTube       *sPass = new GeoTube(5.0*SYSTEM_OF_UNITS::cm, 10*SYSTEM_OF_UNITS::cm, 30*SYSTEM_OF_UNITS::cm);
   GeoLogVol    *lPass = new GeoLogVol("Passive", sPass, steel);
   GeoPhysVol   *pPass = new GeoPhysVol(lPass);
 
@@ -218,6 +219,26 @@ int main(int argc, char *argv[])
   toyPhys->add(pass2Name);
   toyPhys->add(s2);
 
+
+
+  // === Add single test instances for all shapes ===
+
+  // Add a test GeoBox shape
+  GeoBox *sBox = new GeoBox(5.0 * SYSTEM_OF_UNITS::cm, 30 * SYSTEM_OF_UNITS::cm, 30 * SYSTEM_OF_UNITS::cm);
+  GeoLogVol *lBox = new GeoLogVol("box", sBox, steel);
+  GeoPhysVol *pBox = new GeoPhysVol(lBox);
+  GeoNameTag *nBox = new GeoNameTag("Shape-Box");
+  toyPhys->add(nBox);
+  toyPhys->add(pBox);
+
+  // Add a test GeoTube shape
+  GeoTube *sTube = new GeoTube(5.0 * SYSTEM_OF_UNITS::cm, 10 * SYSTEM_OF_UNITS::cm, 30 * SYSTEM_OF_UNITS::cm);
+  GeoLogVol *lTube = new GeoLogVol("tube", sTube, steel);
+  GeoPhysVol *pTube = new GeoPhysVol(lTube);
+  GeoNameTag *nTube = new GeoNameTag("Shape-Tube");
+  toyPhys->add(nTube);
+  toyPhys->add(pTube);
+
   // Add a test GeoPcon shape
   GeoPcon *sPcon = new GeoPcon(0, 360 * SYSTEM_OF_UNITS::deg);
   sPcon->addPlane(1 * SYSTEM_OF_UNITS::m, 1, 5);
@@ -412,6 +433,7 @@ int main(int argc, char *argv[])
 
 
 
+
   //------------------------------------------------------------------------------------//
   // Writing the geometry to file
   //------------------------------------------------------------------------------------//
diff --git a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
index 148cce395..c08cd5f0e 100644
--- a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
+++ b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
@@ -15,6 +15,8 @@
 #ifndef GMDBManager_H
 #define GMDBManager_H
 
+#include "GeoModelDBManager/definitions.h"
+
 // include C++
 #include <iostream>
 #include <string>
@@ -92,6 +94,13 @@ class GMDBManager {
      * @brief Print names of all GeoShape objects in db
      */
     void printAllShapes() const;
+    
+    /**
+     * @brief Print the data related to the GeoShape nodes in the DB 
+     * with a variable number of parameters 
+     * (for example, a variable number of planes along the Z axis)
+     */
+    void printAllShapesData() const;
 
     /**
      * @brief Print names of all GeoSerialDenominator objects in db
@@ -245,13 +254,16 @@ class GMDBManager {
         const std::vector<std::vector<std::string>> &records,
         std::string suffix = "");
 
-    bool addRootVolume(const std::vector<std::string> &values);
+    // bool addRootVolume(const std::vector<std::string> &values);
+    bool addRootVolume(const std::string_view nodeType, const unsigned nodeId);
+    bool addRootVolume(const std::pair<std::string, unsigned> rootValues);
 
     // GET methods
 
     std::string getDBFilePath();
 
-    std::vector<std::string> getRootPhysVol();
+    // std::vector<std::string> getRootPhysVol();
+    std::pair<unsigned, unsigned> getRootPhysVol();
 
     std::vector<std::string> getItemFromTableName(std::string tableName,
                                                   unsigned int id);
@@ -262,7 +274,8 @@ class GMDBManager {
     std::string getNodeTypeFromTableId(unsigned int id);
 
     /// methods to dump the DB
-    std::vector<std::vector<std::string>> getChildrenTable();
+    // std::vector<std::vector<std::string>> getChildrenTable();
+    DBRowsList getChildrenTable();
 
     // Table names for Aux tables are of the form prefix_suffix
     // where prefix depends on the type of data in the table
@@ -270,12 +283,14 @@ class GMDBManager {
 
     // These two require only the suffix, the prefix is already specified based
     // on the table type being accessed
-    std::vector<std::vector<std::string>> getPublishedFPVTable(
-        std::string suffix = "");
-    std::vector<std::vector<std::string>> getPublishedAXFTable(
-        std::string suffix = "");
-
-    std::vector<std::vector<std::string>> getTableFromNodeType(
+    // std::vector<std::vector<std::string>> getPublishedFPVTable(
+    //     std::string suffix = "");
+    // std::vector<std::vector<std::string>> getPublishedAXFTable(
+    //     std::string suffix = "");
+    DBRowsList getPublishedFPVTable(const std::string_view suffix = "");
+    DBRowsList getPublishedAXFTable(const std::string_view suffix = "");
+
+    std::vector<std::vector<std::string>> getTableFromNodeType_String(
         std::string nodeType);
     std::vector<std::vector<std::variant<int, long, float, double, std::string>>> getTableFromNodeType_VecVecData(
         std::string nodeType);
@@ -291,9 +306,9 @@ class GMDBManager {
     std::unordered_map<unsigned int, std::string> getAll_TableIDsNodeTypes();
     std::unordered_map<std::string, unsigned int> getAll_NodeTypesTableIDs();
 
-    std::vector<std::vector<std::string>> getTableRecords(std::string tableName) const;
-    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;
+    std::vector<std::vector<std::string>> getTableRecords_String(const std::string_view tableName) const;
+    std::vector<std::variant<int, long, float, double, std::string>> getTableRecords_VecData(const std::string_view tableName) const;
+    std::vector<std::vector<std::variant<int, long, float, double, std::string>>> getTableRecords_VecVecData(const std::string_view tableName) const;
 
     //! Test if a given table exists
     //! This requires the *full* table name (i.e. prefix_suffix)
@@ -321,7 +336,7 @@ class GMDBManager {
             &records);
 
 
-    unsigned int getTableIdFromNodeType(const std::string &nodeType);
+    unsigned int getTableIdFromNodeType(const std::string_view nodeType);
     // bool createCustomTable(const std::string tableName, const
     // std::vector<std::string> tableColNames, const std::vector<std::string>
     // tableColTypes, const std::vector<std::vector<std::string>> &records ); //
@@ -371,7 +386,7 @@ class GMDBManager {
     int getTableColIndex(const std::string &tableName,
                          const std::string &colName);
 
-    bool storeRootVolume(const unsigned int &id, const std::string &nodeType);
+    bool storeRootVolume(const unsigned &id, const std::string_view nodeType);
 
     std::string m_dbpath;
 
diff --git a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
index c886516c9..1dbf6fb0b 100644
--- a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
+++ b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
@@ -21,7 +21,6 @@
  */
 
 #include <GeoModelDBManager/GMDBManager.h>
-#include "GeoModelDBManager/definitions.h"
 
 #include "GeoModelCppHelpers/GMCppHelpers.h"
 
@@ -61,9 +60,9 @@ class GMDBManager::Imp {
     /// Variable to store error messages from SQLite
     char* m_SQLiteErrMsg;
 
-    sqlite3_stmt* selectAllFromTable(std::string tableName) const;
-    sqlite3_stmt* selectAllFromTableSortBy(std::string tableName,
-                                           std::string sortColumn = "") const;
+    sqlite3_stmt* selectAllFromTable(const std::string_view tableName) const;
+    sqlite3_stmt* selectAllFromTableSortBy(const std::string_view tableName,
+                                           const std::string_view sortColumn = "") const;
     sqlite3_stmt* selectAllFromTableChildrenPositions() const;
     bool checkTable_imp(std::string tableName) const;
 };
@@ -123,7 +122,29 @@ GMDBManager::~GMDBManager() {
 void GMDBManager::printAllMaterials() const { printAllRecords("Materials"); }
 void GMDBManager::printAllElements() const { printAllRecords("Elements"); }
 
-void GMDBManager::printAllShapes() const { printAllRecords("Shapes"); }
+void GMDBManager::printAllShapes() const { 
+    printAllRecords("Shapes_Box"); 
+    printAllRecords("Shapes_Tube"); 
+    printAllRecords("Shapes_Cons"); 
+    printAllRecords("Shapes_Para");
+    printAllRecords("Shapes_Trap"); 
+    printAllRecords("Shapes_Trd"); 
+    printAllRecords("Shapes_Tubs"); 
+    printAllRecords("Shapes_TwistedTrap"); 
+    printAllRecords("Shapes_Pcon"); 
+    printAllRecords("Shapes_Pgon"); 
+    printAllRecords("Shapes_SimplePolygonBrep"); 
+    printAllRecords("Shapes_Intersection"); 
+    printAllRecords("Shapes_Shift"); 
+    printAllRecords("Shapes_Subtraction"); 
+    printAllRecords("Shapes_Union"); 
+}
+
+void GMDBManager::printAllShapesData() const { 
+    printAllRecords("Shapes_Pcon_Data");
+    printAllRecords("Shapes_Pgon_Data");
+    printAllRecords("Shapes_SimplePolygonBrep_Data");
+}
 
 void GMDBManager::printAllSerialDenominators() const {
     printAllRecords("SerialDenominators");
@@ -201,7 +222,7 @@ void GMDBManager::printAllRecords(const std::string& tableName) const {
     // --- print records
     std::vector<std::vector<std::string>> records;
     //  std::vector<std::string> nodeParams;
-    records = getTableRecords(tableName);
+    records = getTableRecords_String(tableName);
     if (records.size()) {
         for (auto& row : records) {
             std::cout << "* ";
@@ -216,12 +237,8 @@ void GMDBManager::printAllRecords(const std::string& tableName) const {
     // query gives 0 results.
 }
 
-// FIXME: TODO: we now return all records as text, but should we get
-// double/int instead when appropriate? In that case, we should create
-// dedicated methods for all tables, I guess.
-// TODO: fill a cache and returns that if asked a second time
-std::vector<std::vector<std::string>> GMDBManager::getTableRecords(
-    std::string tableName) const {
+std::vector<std::vector<std::string>> GMDBManager::getTableRecords_String(
+    const std::string_view tableName) const {
 
     // container to be returned
     std::vector<std::vector<std::string>> records;
@@ -277,9 +294,8 @@ std::vector<std::vector<std::string>> GMDBManager::getTableRecords(
     return records;
 }
 
-// New version with variant
 std::vector<std::vector<std::variant<int, long, float, double, std::string>>> GMDBManager::getTableRecords_VecVecData(
-    std::string tableName) const
+    const std::string_view tableName) const
 {
     
     // container to be returned
@@ -394,10 +410,10 @@ std::vector<std::vector<std::variant<int, long, float, double, std::string>>> GM
 }
 // New version with variant
 std::vector<std::variant<int, long, float, double, std::string>> GMDBManager::getTableRecords_VecData(
-    std::string tableName) const
+    const std::string_view tableName) const
 {
     if (!checkTableFromCache(tableName)) {
-        THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
+        THROW_EXCEPTION("ERROR!!! Table name '" + std::string(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;
@@ -509,7 +525,7 @@ std::vector<std::variant<int, long, float, double, std::string>> GMDBManager::ge
     return records;
 }
 
-std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType(
+std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType_String(
     std::string nodeType)
 {
     std::vector<std::vector<std::string>> out;
@@ -535,7 +551,7 @@ std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType(
         {
             THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
         }
-        out = getTableRecords(tableName);
+        out = getTableRecords_String(tableName);
     }
     return out;
 }
@@ -681,13 +697,16 @@ bool GMDBManager::addListOfPublishedAlignableTransforms(
     std::string nodeType = "GeoAlignableTransform";
     const std::type_info& keyType(
         typeid(std::string));  // TODO: type should be custom too!!
-    if ("" != suffix) {
+    if ("" != suffix)
+    {
         tableName += "_";
         tableName += suffix;
-        // debug msg
-        // std::cout << "\nSaving the published '"<< nodeType << "' nodes to
-        // the custom table: '"
-        //          << tableName << "'." << std::endl;
+        if (m_debug)
+        {
+            std::cout << "\nSaving the published '" << nodeType
+                      << "' nodes to the custom table : '" << tableName
+                      << "'." << std::endl;
+        }
     }
     // create custom table first then add to it
     createTableCustomPublishedNodes(tableName, nodeType, &keyType);
@@ -702,12 +721,16 @@ bool GMDBManager::addListOfPublishedFullPhysVols(
     std::string nodeType = "GeoFullPhysVol";
     const std::type_info& keyType(
         typeid(std::string));  // TODO: type should be custom too!!
-    if ("" != suffix) {
+    if ("" != suffix)
+    {
         tableName += "_";
         tableName += suffix;
-        // std::cout << "\nSaving the published '"<< nodeType << "' nodes to
-        // the custom table: '"
-        //           << tableName << "'." << std::endl;
+        if (m_debug)
+        {
+            std::cout << "\nSaving the published '" << nodeType
+                      << "' nodes to the custom table : '"
+                      << tableName << "'." << std::endl;
+        }
     }
     // create custom table first then add to it
     createTableCustomPublishedNodes(tableName, nodeType, &keyType);
@@ -814,9 +837,6 @@ bool GMDBManager::addListOfRecordsToTable(
     return true;
 }
 
-// TODO: use this with std::variant to replace the version with std::string
-// only, here above, for all tables; so we can store native values (int,
-// double, etc...) -- R.M.B.
 bool GMDBManager::addListOfRecordsToTable(
     const std::string tableName,
     const std::vector<
@@ -981,17 +1001,18 @@ bool GMDBManager::addRecordsToTable(
 }
 
 
-bool GMDBManager::addRootVolume(const std::vector<std::string>& values) {
-    if (values.size() > 0) {
-        const unsigned int volId = std::stoi(values[0]);
-        const std::string nodeType = values[1];
-        return storeRootVolume(volId, nodeType);
-    } else {
-        std::cout << "ERROR! No records to save for RootVolume! All GeoModel "
-                     "trees must have a 'World'/'Root' volume! Exiting..."
-                  << std::endl;
-        exit(EXIT_FAILURE);
-    }
+// bool GMDBManager::addRootVolume(const std::vector<std::string>& values) {
+bool GMDBManager::addRootVolume(const std::string_view type, const unsigned id)
+{
+    const std::string nodeType{type};
+    const unsigned int volId{id};
+    return storeRootVolume(volId, nodeType);
+}
+bool GMDBManager::addRootVolume(const std::pair<std::string, unsigned> rootValues)
+{
+    const std::string nodeType{rootValues.first};
+    const unsigned int volId{rootValues.second};
+    return storeRootVolume(volId, nodeType);
 }
 
 void GMDBManager::addDBversion(std::string version) {
@@ -1112,12 +1133,13 @@ std::vector<std::string> GMDBManager::getItemFromTableName(
 }
 
 // Get all parent-children data from the database in one go
-std::vector<std::vector<std::string>> GMDBManager::getChildrenTable() {
-    return getTableRecords("ChildrenPositions");
+DBRowsList GMDBManager::getChildrenTable() {
+    return getTableRecords_VecVecData("ChildrenPositions");
 }
 
-unsigned int GMDBManager::getTableIdFromNodeType(const std::string& nodeType) {
-    return m_cache_nodeType_tableID[nodeType];
+unsigned int GMDBManager::getTableIdFromNodeType(const std::string_view nodeType) {
+    if (m_cache_nodeType_tableID.empty()) THROW_EXCEPTION("ERROR! Cache is empty!");
+    return m_cache_nodeType_tableID[std::string(nodeType)];
 }
 
 std::string GMDBManager::getTableNameFromNodeType(const std::string& nodeType) {
@@ -1185,14 +1207,13 @@ int GMDBManager::loadGeoNodeTypesAndBuildCache() {
     return rc;
 }
 
-// FIXME: should throw an error if the method
-// `loadGeoNodeTypesAndBuildCache()` was not called before calling this
-// method
 std::string GMDBManager::getTableNameFromTableId(unsigned int tabId) {
+    if (m_cache_tableId_tableName.empty()) THROW_EXCEPTION("ERROR! Cache is empty!");
     return m_cache_tableId_tableName[tabId];
 }
 
 std::string GMDBManager::getNodeTypeFromTableId(unsigned int tabId) {
+    if (m_cache_tableId_nodeType.empty()) THROW_EXCEPTION("ERROR! Cache is empty!");
     return m_cache_tableId_nodeType[tabId];
 }
 
@@ -1207,12 +1228,13 @@ GMDBManager::getAll_NodeTypesTableIDs() {
 }
 
 sqlite3_stmt* GMDBManager::Imp::selectAllFromTable(
-    std::string tableName) const {
+    const std::string_view tableName) const {
     return selectAllFromTableSortBy(tableName, "id");
 }
 
 sqlite3_stmt* GMDBManager::Imp::selectAllFromTableSortBy(
-    std::string tableName, std::string sortColumn) const {
+    const std::string_view tableName, const std::string_view sortCol) const {
+    std::string sortColumn{sortCol};
     theManager->checkIsDBOpen();
     if ("" == sortColumn || 0 == sortColumn.size()) {
         sortColumn = "id";
@@ -1363,10 +1385,11 @@ void GMDBManager::getAllDBTableColumns() {
 
 // TODO: currently, we retrieve published data as strings, but we want to
 // retrieve that according to the original data type
-std::vector<std::vector<std::string>> GMDBManager::getPublishedFPVTable(
-    std::string suffix) {
+// std::vector<std::vector<std::string>> GMDBManager::getPublishedFPVTable(
+DBRowsList GMDBManager::getPublishedFPVTable(
+    const std::string_view suffix) {
     std::string tableName = "PublishedFullPhysVols";  // default table name
-    if ("" != suffix) {
+    if ( !suffix.empty() ) {
         tableName += "_";
         tableName += suffix;
     }
@@ -1374,15 +1397,16 @@ std::vector<std::vector<std::string>> GMDBManager::getPublishedFPVTable(
     {
         THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
     }
-    return getTableRecords(tableName);
+    return getTableRecords_VecVecData(tableName);
 }
 // TODO: currently, we retrieve published data as strings, but we want to
 // retrieve that according to the original data type
-std::vector<std::vector<std::string>> GMDBManager::getPublishedAXFTable(
-    std::string suffix) {
+// std::vector<std::vector<std::string>> GMDBManager::getPublishedAXFTable(
+DBRowsList GMDBManager::getPublishedAXFTable(
+    const std::string_view suffix) {
     std::string tableName =
         "PublishedAlignableTransforms";  // default table name
-    if ("" != suffix) {
+    if ( !suffix.empty() ) {
         tableName += "_";
         tableName += suffix;
     }
@@ -1390,7 +1414,7 @@ std::vector<std::vector<std::string>> GMDBManager::getPublishedAXFTable(
     {
         THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in cache! (It has not been loaded from the DB)");
     }
-    return getTableRecords(tableName);
+    return getTableRecords_VecVecData(tableName);
 }
 
 bool GMDBManager::checkTable(std::string tableName) const {
@@ -1491,6 +1515,7 @@ bool GMDBManager::createCustomTable(
     for (size_t ii = 0; ii < tableColNames.size(); ++ii) {
         std::string colType = "";
 
+        // *** NOTE: ***
         // -- Here we check the datum's type, which is more universal than
         // using string-encoded types
         // -- but this does not work if the first entry of a given column is
@@ -1763,23 +1788,23 @@ bool GMDBManager::createTables() {
     }
     tab.clear();
 
-    // Shapes table
-    geoNode = "GeoShape";
-    tableName = "Shapes";
-    m_childType_tableName[geoNode] = tableName;
-    tab.push_back(tableName);
-    tab.push_back("id");
-    tab.push_back("type");
-    tab.push_back("parameters");
-    storeTableColumnNames(tab);
-    queryStr = fmt::format(
-        "create table {0}({1} integer primary key, {2} varchar, {3} "
-        "varchar)",
-        tab[0], tab[1], tab[2], tab[3]);
-    if (0 == (rc = execQuery(queryStr))) {
-        storeNodeType(geoNode, tableName);
-    }
-    tab.clear();
+    // // Shapes table
+    // geoNode = "GeoShape";
+    // tableName = "Shapes";
+    // m_childType_tableName[geoNode] = tableName;
+    // tab.push_back(tableName);
+    // tab.push_back("id");
+    // tab.push_back("type");
+    // tab.push_back("parameters");
+    // storeTableColumnNames(tab);
+    // queryStr = fmt::format(
+    //     "create table {0}({1} integer primary key, {2} varchar, {3} "
+    //     "varchar)",
+    //     tab[0], tab[1], tab[2], tab[3]);
+    // if (0 == (rc = execQuery(queryStr))) {
+    //     storeNodeType(geoNode, tableName);
+    // }
+    // tab.clear();
 
     // Shapes-Box table
     // ID, XHalfLength, YHalfLength, ZHalfLength
@@ -2383,8 +2408,8 @@ void GMDBManager::storeNodeType(std::string nodeType, std::string tableName) {
 //  QVariant childPhysId = addPhysVol(toyLogId, rootPhysId);
 //}
 
-bool GMDBManager::storeRootVolume(const unsigned int& id,
-                                  const std::string& nodeType) {
+bool GMDBManager::storeRootVolume(const unsigned &id,
+                                  const std::string_view nodeType) {
     checkIsDBOpen();
 
     std::string tableName = "RootVolume";
@@ -2426,7 +2451,8 @@ bool GMDBManager::storeRootVolume(const unsigned int& id,
     return true;
 }
 
-std::vector<std::string> GMDBManager::getRootPhysVol() {
+// std::vector<std::string> GMDBManager::getRootPhysVol() {
+std::pair<unsigned, unsigned> GMDBManager::getRootPhysVol() {
     // get the ID of the ROOT vol from the table "RootVolume"
     sqlite3_stmt* stmt = m_d->selectAllFromTable("RootVolume");
     // declare the data we want to fetch
@@ -2448,8 +2474,8 @@ std::vector<std::string> GMDBManager::getRootPhysVol() {
     // finalize
     sqlite3_finalize(stmt);
     
-    std::vector<std::string> results = getItemAndType(typeId, id);
-    return results;
+    // std::vector<std::string> results = getItemAndType(typeId, id);
+    return std::pair<unsigned, unsigned>{typeId, id};
     
 }
 
diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
index 8da4790db..d30fa9ac8 100644
--- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
+++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
@@ -172,9 +172,9 @@ class ReadGeoModel {
     unsigned long getNNameTags() { return m_nameTags.size(); };
     unsigned long getNShapes() { return m_shapes.size(); };
     unsigned long getNChildrenConnections() { return m_allchildren.size(); };
-    std::vector<std::vector<std::string>> getTableFromTableName(
-        std::string tableName) {
-        return m_dbManager->getTableRecords(tableName);
+    std::vector<std::vector<std::string>> getTableFromTableName_String(
+        const std::string_view tableName) {
+        return m_dbManager->getTableRecords_String(tableName);
     };
 
    private:
@@ -400,11 +400,12 @@ class ReadGeoModel {
     std::vector<std::vector<std::string>> m_identifierTags;
     std::vector<std::vector<std::string>> m_serialTransformers;
     std::vector<std::vector<std::string>> m_nameTags;
-    std::vector<std::vector<std::string>> m_materials;
+    // std::vector<std::vector<std::string>> m_materials;
     std::vector<std::vector<std::string>> m_elements;
     std::vector<std::vector<std::string>> m_shapes;
     std::vector<std::vector<std::string>> m_allchildren;
 
+    DBRowsList m_materials;
     DBRowsList m_logVols;
 
     // containers to store shapes' parameters
diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp
index 82d3f4a91..1e383e844 100644
--- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp
+++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp
@@ -1,3 +1,6 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
 /* vim: set ft=cpp: */ // VIM modeline options
 /*
  * ReadGeoModel.tpp
@@ -11,6 +14,10 @@
 
 #include "GeoModelKernel/GeoFullPhysVol.h"
 
+#include "GeoModelHelpers/variantHelpers.h"
+#include "GeoModelHelpers/throwExcept.h"
+
+
 
 namespace GeoModelIO {
 
@@ -21,7 +28,9 @@ namespace GeoModelIO {
         std::map<T, N> mapNodes;
         std::string keyType = "";
 
-        std::vector<std::vector<std::string>> vecRecords;
+        // std::vector<std::vector<std::string>> vecRecords;
+        DBRowsList vecRecords;
+
         static_assert(std::is_same_v<GeoFullPhysVol*, N> || std::is_same_v<GeoAlignableTransform*, N> ,
                     "ERROR! The node type is not currently supported. If in doubt, please ask to 'geomodel-developers@cern.ch'.\n");
 
@@ -41,15 +50,15 @@ namespace GeoModelIO {
         unsigned ii = 0;
         for( auto const &record : vecRecords ) {
             // record[0] is the record's ID in the DB table, we skip that.
-            std::string keyStr  = record[1];
-            std::string volID   = record[2];
-            if(0==ii) keyType   = record[3];//this is the same for all records. TODO: it should be stored in a metadata table
+            const std::string keyStr  = GeoModelHelpers::variantHelper::getFromVariant_String(record[1], "getPublishedNodes:keyStr");
+            const unsigned volID   = GeoModelHelpers::variantHelper::getFromVariant_Int(record[2], "getPublishedNodes:volID");
+            if(0==ii) keyType   = GeoModelHelpers::variantHelper::getFromVariant_String(record[3], "getPublishedNodes:keyType"); //this is the same for all records. TODO: it should be stored in a metadata table
             ++ii;
             N volPtr = nullptr;
             if constexpr ( std::is_same_v<GeoFullPhysVol*, N> ) {
-                volPtr = dynamic_cast<GeoFullPhysVol*>( getVPhysVol(std::stoul(volID), 2) ); //always table=2, and we should have copyN=1 because FullPhysVols are not sharable 
+                volPtr = dynamic_cast<GeoFullPhysVol*>( getVPhysVol(volID, 2) ); //always table=2, and we should have copyN=1 because FullPhysVols are not sharable 
             } else if constexpr ( std::is_same_v<GeoAlignableTransform*, N> ) {
-                volPtr = getBuiltAlignableTransform(std::stoul(volID));
+                volPtr = getBuiltAlignableTransform(volID);
             } else {
                 std::cout << "ERROR! The node type '" << typeid(N).name() 
                     << "' is not currently supported.\n"
@@ -58,6 +67,7 @@ namespace GeoModelIO {
                 exit(EXIT_FAILURE);
             }
 
+            //TODO: check if we can get rid of stoul/stoi...
             if constexpr ( std::is_same_v<unsigned, T> ) {
                 unsigned int key = std::stoul( keyStr );
                 mapNodes.insert( {key, volPtr} );
@@ -71,10 +81,11 @@ namespace GeoModelIO {
                 mapNodes.insert( {keyStr, volPtr} );
             } 
             else {
-                std::cout << "ERROR! Key type '" << keyType << "' is not currently supported.\n"
-                          << "If in doubt, please ask to 'geomodel-developers@cern.ch'.\n"
-                          << "Exiting...\n";
-                exit(EXIT_FAILURE);
+                const std::string errMsg = "ERROR! Key type '" + keyType + "' is not currently supported.\n"
+                          + "For the moment, unsigned int, int, and string are supported.\n" 
+                          + "If in doubt, please ask to 'geomodel-developers@cern.ch'.\n"
+                          + "Exiting...\n";
+                THROW_EXCEPTION(errMsg);
             }
         }
         return mapNodes;
diff --git a/GeoModelIO/GeoModelRead/src/NOTES_UPDATE.md b/GeoModelIO/GeoModelRead/src/NOTES_UPDATE.md
new file mode 100644
index 000000000..31527e93f
--- /dev/null
+++ b/GeoModelIO/GeoModelRead/src/NOTES_UPDATE.md
@@ -0,0 +1,51 @@
+
+
+List of all Shapes
+
+- Box
+- Tube
+- Cons
+- Para
+- Trap
+- Trd
+- TwistedTrap
+- Tubs
+- Pcon
+- Pgon
+- SimplePolygonBrep
+
+- Torus
+- GenericTrap
+- TessellatedSolid
+- Shift
+- Subtraction || Union || Intersection
+- CustomShape
+
+
+Write
+
+- Box
+- Tube
+- Cons
+- Para
+- Trap
+- Trd
+- Tubs
+- TwistedTrap
+- Pcon
+- Pgon
+- SimplePolygonBrep
+
+Read
+
+- Box
+- Tube
+- Cons
+- Para
+- Trap
+- Trd
+- Tubs
+- TwistedTrap
+- Pcon
+- Pgon
+- SimplePolygonBrep
diff --git a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
index 806b8bf34..20c2ef088 100644
--- a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
+++ b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
@@ -274,10 +274,10 @@ const GeoVPhysVol* ReadGeoModel::buildGeoModel() {
 
 void ReadGeoModel::loadDB() {
     // *** get all data from the DB ***
-    std::chrono::system_clock::time_point start =
-        std::chrono::system_clock::now();  // timing: get start time
+    // timing: get start time
+    std::chrono::system_clock::time_point start = std::chrono::system_clock::now();  
     // get all GeoModel nodes from the DB
-    m_shapes = m_dbManager->getTableFromNodeType("GeoShape");
+    // m_shapes = m_dbManager->getTableFromNodeType("GeoShape");
     m_materials = m_dbManager->getTableFromNodeType("GeoMaterial");
     m_elements = m_dbManager->getTableFromNodeType("GeoElement");
     m_physVols = m_dbManager->getTableFromNodeType("GeoPhysVol");
@@ -1598,12 +1598,18 @@ GeoMaterial* ReadGeoModel::buildMaterial(const unsigned int id) {
         std::cout << "ReadGeoModel::buildMaterial()" << std::endl;
         muxCout.unlock();
     }
-    std::vector<std::string> values = m_materials[id - 1];
+    // std::vector<std::string> values = m_materials[id - 1];
+    DBRowEntry values = m_materials[id - 1];
+
+    // const unsigned int matId = std::stoi(values[0]);
+    // const std::string matName = values[1];
+    // double matDensity = std::stod(values[2]);
+    // std::string matElements = values[3];
 
-    const unsigned int matId = std::stoi(values[0]);
-    const std::string matName = values[1];
-    double matDensity = std::stod(values[2]);
-    std::string matElements = values[3];
+    const unsigned int matId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Material:id");
+    const std::string matName = GeoModelHelpers::variantHelper::getFromVariant_String(row[0], "Material:matName");
+    const double matDensity = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Material:matDensity");
+    const std::string matElements = GeoModelHelpers::variantHelper::getFromVariant_String(row[0], "Material:matElements");
 
     if (m_loglevel >= 2) {
         muxCout.lock();
diff --git a/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h b/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
index f04e373ee..a98fb53d4 100644
--- a/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
+++ b/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
@@ -389,7 +389,9 @@ class WriteGeoModel : public GeoNodeAction {
     std::vector<std::variant<int, long, float, double, std::string>> m_exprData; // numbers used in Function's expression
 
     // caches for Metadata to be saved into the DB
-    std::vector<std::string> m_rootVolume;
+    // std::vector<std::string> m_rootVolume;
+    std::pair<std::string, unsigned> m_rootVolume;
+
     std::vector<std::vector<std::string>> m_childrenPositions;
     std::vector<std::vector<std::string>> m_publishedAlignableTransforms_String;
     std::vector<std::vector<std::string>> m_publishedFullPhysVols_String;
diff --git a/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp b/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp
index aafc59d81..3aae3d595 100644
--- a/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp
+++ b/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp
@@ -2482,9 +2482,10 @@ unsigned int WriteGeoModel::addPhysVol(const unsigned int& logVolId,
     values.push_back(std::to_string(logVolId));  // INT
     unsigned int idx = addRecord(container, values);
     if (isRootVolume) {
-        std::vector<std::string> rootValues;
-        rootValues.insert(rootValues.begin(),
-                          {std::to_string(idx), "GeoPhysVol"});  // INT
+        // std::vector<std::string> rootValues;
+        // rootValues.insert(rootValues.begin(),
+        //                   {std::to_string(idx), "GeoPhysVol"});  // INT
+        std::pair<std::string, unsigned> rootValues{"GeoPhysVol", idx};
         m_rootVolume = rootValues;
     }
     return idx;
@@ -2498,9 +2499,10 @@ unsigned int WriteGeoModel::addFullPhysVol(
     values.push_back(std::to_string(logVolId));  // INT
     unsigned int idx = addRecord(container, values);
     if (isRootVolume) {
-        std::vector<std::string> rootValues;
-        rootValues.insert(rootValues.begin(),
-                          {std::to_string(idx), "GeoFullPhysVol"});  // INT
+        // std::vector<std::string> rootValues;
+        // rootValues.insert(rootValues.begin(),
+        //                   {std::to_string(idx), "GeoFullPhysVol"});  // INT
+        std::pair<std::string, unsigned> rootValues{"GeoFullPhysVol", idx};
         m_rootVolume = rootValues;
     }
     return idx;
diff --git a/GeoModelVisualization/VP1GeometryPlugin/CMakeLists.txt b/GeoModelVisualization/VP1GeometryPlugin/CMakeLists.txt
index 052eb9156..027c4f5cd 100644
--- a/GeoModelVisualization/VP1GeometryPlugin/CMakeLists.txt
+++ b/GeoModelVisualization/VP1GeometryPlugin/CMakeLists.txt
@@ -23,7 +23,8 @@ add_library( GeoModelVisualization::GXGeometryPlugin ALIAS GXGeometryPlugin )
 install( TARGETS GXGeometryPlugin
    EXPORT ${PROJECT_NAME}-export
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/gxplugins
-   COMPONENT Runtime )
+   COMPONENT Runtime 
+   NAMELINK_COMPONENT Development )
 install( FILES ${HEADERS}
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/VP1GeometryPlugin
    COMPONENT Development )
diff --git a/GeoModelVisualization/VP1GeometrySystems/src/SoVisualizeAction.cxx b/GeoModelVisualization/VP1GeometrySystems/src/SoVisualizeAction.cxx
index f94ba74b9..888ad34e2 100644
--- a/GeoModelVisualization/VP1GeometrySystems/src/SoVisualizeAction.cxx
+++ b/GeoModelVisualization/VP1GeometrySystems/src/SoVisualizeAction.cxx
@@ -45,13 +45,12 @@ SoVisualizeAction::SoVisualizeAction()
 
 SoVisualizeAction::~SoVisualizeAction()
 {
-  // Don't delete.  Let ref count take care of the memory.
+  // NOTE: Don't delete.  Let ref count take care of the memory.
 }
 
 
 void SoVisualizeAction::handleShape(const GeoShape *shape)
 {
-  //qDebug() << "SoVisualizeAction::handleShape";
   // We don't recognize it.  Try to polyhedrize it!
   SbPolyhedrizeAction a;
   shape->exec(&a);
@@ -65,7 +64,6 @@ void SoVisualizeAction::handleShape(const GeoShape *shape)
 
 void SoVisualizeAction::handleBox(const GeoBox *box)
 {
-  //qDebug() << "SoVisualizeAction::handleBox";
   SoGenericBox * gb = new SoGenericBox;
   gb->setParametersForBox( box->getXHalfLength(),box->getYHalfLength(),box->getZHalfLength() );
   m_shape=gb;
@@ -73,7 +71,6 @@ void SoVisualizeAction::handleBox(const GeoBox *box)
 
 void SoVisualizeAction::handleCons(const GeoCons *cons)
 {
-  //qDebug() << "SoVisualizeAction::handleCons";
   SoCons::initClass();
   SoCons *socons= new SoCons;
   socons->fRmin1 =cons->getRMin1();
@@ -89,7 +86,6 @@ void SoVisualizeAction::handleCons(const GeoCons *cons)
 
 void SoVisualizeAction::handleTorus(const GeoTorus *torus)
 {
-  //qDebug() << "SoVisualizeAction::handleTorus";
   SoTorus::initClass();
   SoTorus *sotorus= new SoTorus;
   sotorus->fRInner = torus->getRMin();
@@ -103,9 +99,6 @@ void SoVisualizeAction::handleTorus(const GeoTorus *torus)
 
 void SoVisualizeAction::handlePcon(const GeoPcon *pcon)
 {
-
-  //qDebug() << "SoVisualizeAction::handlePcon";
-
   //Set up temporary data arrays for profile:
   float *z  = new float[pcon->getNPlanes()];
   float *rmn= new float[pcon->getNPlanes()];
@@ -136,7 +129,6 @@ void SoVisualizeAction::handlePcon(const GeoPcon *pcon)
 
 void SoVisualizeAction::handleTrap(const GeoTrap *trap)
 {
-  //qDebug() << "SoVisualizeAction::handleTrap";
   SoGenericBox * gb = new SoGenericBox;
   gb->setParametersForTrapezoid(trap->getZHalfLength(), trap->getTheta(), trap->getPhi(),
 				trap->getDydzn(), trap->getDxdyndzn(), trap->getDxdypdzn(),
@@ -158,7 +150,6 @@ void SoVisualizeAction::handleTwistedTrap(const GeoTwistedTrap *twistedtrap)
 
 void SoVisualizeAction::handleTrd(const GeoTrd *trd)
 {
-  //qDebug() << "SoVisualizeAction::handleTrd";
   SoGenericBox * gb = new SoGenericBox;
   gb->setParametersForTrd( trd->getXHalfLength1(), trd->getXHalfLength2(),
 			   trd->getYHalfLength1(), trd->getYHalfLength2(),
@@ -168,7 +159,6 @@ void SoVisualizeAction::handleTrd(const GeoTrd *trd)
 
 void SoVisualizeAction::handleTube(const GeoTube *tube)
 {
-  //qDebug() << "SoVisualizeAction::handleTube";
   SoTubs *sotubs= new SoTubs;
   sotubs->pRMin= tube->getRMin();
   sotubs->pRMax= tube->getRMax();
@@ -180,7 +170,6 @@ void SoVisualizeAction::handleTube(const GeoTube *tube)
 
 void SoVisualizeAction::handleTubs(const GeoTubs *tubs)
 {
-  //qDebug() << "SoVisualizeAction::handleTubs";
   SoTubs *sotubs= new SoTubs;
   sotubs->pRMin= tubs->getRMin();
   sotubs->pRMax= tubs->getRMax();
@@ -192,9 +181,7 @@ void SoVisualizeAction::handleTubs(const GeoTubs *tubs)
 
 void SoVisualizeAction::handleSimplePolygonBrep(const GeoSimplePolygonBrep *brep)
 {
-  //qDebug() << "SoVisualizeAction::handleSimplePolygonBrep";
   //Fixme: Detect if order of vertices is the wrong way around... and reorder if necessary.
-
   double dz = brep->getDZ();
   std::vector<double> x, y;
   for(unsigned int i=0; i<brep->getNVertices(); ++i)
@@ -210,8 +197,6 @@ void SoVisualizeAction::handleSimplePolygonBrep(const GeoSimplePolygonBrep *brep
 
 void SoVisualizeAction::handleTessellatedSolid (const GeoTessellatedSolid* geoTessellated)
 {
-  //std::cout << "SoVisualizeAction::handleTessellatedSolid" << std::endl;
-
   SoTessellated * soTessellated = new SoTessellated;
 
   //std::cout << "\tn. facets: " << geoTessellated->getNumberOfFacets() << std::endl;
@@ -270,7 +255,6 @@ void SoVisualizeAction::handleTessellatedSolid (const GeoTessellatedSolid* geoTe
 
 void SoVisualizeAction::handleGenericTrap(const GeoGenericTrap *gentrap)
 {
-  //qDebug() << "SoVisualizeAction::handleGenericTrap";
   SoGenericBox * gb = new SoGenericBox;
   const GeoGenericTrapVertices& trapVertices = gentrap->getVertices();
   double dZ = gentrap->getZHalfLength();
diff --git a/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandleSharedData.cxx b/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandleSharedData.cxx
index 0ff86e8b5..a12d57dd2 100644
--- a/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandleSharedData.cxx
+++ b/GeoModelVisualization/VP1GeometrySystems/src/VolumeHandleSharedData.cxx
@@ -136,25 +136,38 @@ void VolumeHandleSharedData::registerNodeSepForVolumeHandle(SoSeparator*n,Volume
 //_____________________________________________________________________________________
 void VolumeHandleSharedData::setShowVolumeOutlines(SoGroup*nodegroup,bool showvol)
 {
-  for (int i = 0; i<nodegroup->getNumChildren();++i) {
-    SoNode * n = nodegroup->getChild(i);
-    if (n->getTypeId().isDerivedFrom(SoGenericBox::getClassTypeId())) {
-      if (static_cast<SoGenericBox*>(n)->drawEdgeLines.getValue()!=showvol)
-        static_cast<SoGenericBox*>(n)->drawEdgeLines.setValue(showvol);
-    } else if (n->getTypeId().isDerivedFrom(SoTubs::getClassTypeId())) {
-      if (static_cast<SoTubs*>(n)->drawEdgeLines.getValue()!=showvol){
-	static_cast<SoTubs*>(n)->drawEdgeLines.setValue(showvol);
+  for (int i = 0; i < nodegroup->getNumChildren(); ++i)
+  {
+    SoNode *n = nodegroup->getChild(i);
+    if (n->getTypeId().isDerivedFrom(SoGenericBox::getClassTypeId()))
+    {
+      if (static_cast<SoGenericBox *>(n)->drawEdgeLines.getValue() != showvol)
+        static_cast<SoGenericBox *>(n)->drawEdgeLines.setValue(showvol);
+    }
+    else if (n->getTypeId().isDerivedFrom(SoTubs::getClassTypeId()))
+    {
+      if (static_cast<SoTubs *>(n)->drawEdgeLines.getValue() != showvol)
+      {
+        static_cast<SoTubs *>(n)->drawEdgeLines.setValue(showvol);
       }
-    } else if (n->getTypeId().isDerivedFrom(SoPcons::getClassTypeId())) {
-      if (static_cast<SoPcons*>(n)->drawEdgeLines.getValue()!=showvol){
-        static_cast<SoPcons*>(n)->drawEdgeLines.setValue(showvol);
+    }
+    else if (n->getTypeId().isDerivedFrom(SoPcons::getClassTypeId()))
+    {
+      if (static_cast<SoPcons *>(n)->drawEdgeLines.getValue() != showvol)
+      {
+        static_cast<SoPcons *>(n)->drawEdgeLines.setValue(showvol);
       }
-    } else if (n->getTypeId().isDerivedFrom(SoTessellated::getClassTypeId())) {
-      if (static_cast<SoTessellated*>(n)->drawEdgeLines.getValue()!=showvol){
-        static_cast<SoTessellated*>(n)->drawEdgeLines.setValue(showvol);
+    }
+    else if (n->getTypeId().isDerivedFrom(SoTessellated::getClassTypeId()))
+    {
+      if (static_cast<SoTessellated *>(n)->drawEdgeLines.getValue() != showvol)
+      {
+        static_cast<SoTessellated *>(n)->drawEdgeLines.setValue(showvol);
       }
-    } else if (n->getTypeId().isDerivedFrom(SoGroup::getClassTypeId())) {
-      setShowVolumeOutlines(static_cast<SoGroup*>(n),showvol);
+    }
+    else if (n->getTypeId().isDerivedFrom(SoGroup::getClassTypeId()))
+    {
+      setShowVolumeOutlines(static_cast<SoGroup *>(n), showvol);
     }
   }
 }
-- 
GitLab