diff --git a/src/Mod/Assembly/App/BomObject.cpp b/src/Mod/Assembly/App/BomObject.cpp index 49dc7e2a1f..673a9bfbc6 100644 --- a/src/Mod/Assembly/App/BomObject.cpp +++ b/src/Mod/Assembly/App/BomObject.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -239,6 +240,16 @@ void BomObject::addObjectToBom(App::DocumentObject* obj, size_t row, std::string else if (columnName == "Quantity") { setCell(App::CellAddress(row, col), std::to_string(1).c_str()); } + else if (columnName.starts_with(".")) { + // Column names that start with a dot are considered property names + // Extract the property name + std::string baseName = columnName.substr(1); + + auto propertyValue = getBomPropertyValue(obj, baseName); + if (!propertyValue.empty()) { + setCell(App::CellAddress(row, col), propertyValue.c_str()); + } + } else { // load custom data if any. for (auto& el : dataElements) { @@ -252,6 +263,39 @@ void BomObject::addObjectToBom(App::DocumentObject* obj, size_t row, std::string } } +std::string BomObject::getBomPropertyValue(App::DocumentObject* obj, const std::string& baseName) +{ + App::Property* prop = obj->getPropertyByName(baseName.c_str()); + + if (!prop) { + Base::Console().Warning("Property not found: %s\n", baseName.c_str()); + return QObject::tr("N/A").toStdString(); + } + + // Only support a subset of property types for BOM + if (auto propStr = freecad_cast(prop)) { + return propStr->getValue(); + } + else if (auto propQuantity = freecad_cast(prop)) { + return propQuantity->getQuantityValue().getUserString(); + } + else if (auto propEnum = freecad_cast(prop)) { + return propEnum->getValueAsString(); + } + else if (auto propFloat = freecad_cast(prop)) { + return std::to_string(propFloat->getValue()); + } + else if (auto propInt = freecad_cast(prop)) { + return std::to_string(propInt->getValue()); + } + else if (auto propBool = freecad_cast(prop)) { + return propBool->getValue() ? "True" : "False"; + } + + Base::Console().Warning("Property type not supported for: %s\n", prop->getName()); + return QObject::tr("Not supported").toStdString(); +} + AssemblyObject* BomObject::getAssembly() { for (auto& obj : getInList()) { diff --git a/src/Mod/Assembly/App/BomObject.h b/src/Mod/Assembly/App/BomObject.h index 9b6666878d..7d0950830d 100644 --- a/src/Mod/Assembly/App/BomObject.h +++ b/src/Mod/Assembly/App/BomObject.h @@ -94,6 +94,9 @@ public: std::vector dataElements; std::vector obj_list; + +private: + std::string getBomPropertyValue(App::DocumentObject* obj, const std::string& baseName); }; diff --git a/src/Mod/Assembly/CommandCreateBom.py b/src/Mod/Assembly/CommandCreateBom.py index 6b5a55621c..af4eee28a1 100644 --- a/src/Mod/Assembly/CommandCreateBom.py +++ b/src/Mod/Assembly/CommandCreateBom.py @@ -402,7 +402,7 @@ class TaskAssemblyCreateBom(QtCore.QObject): " - " + translate( "Assembly", - "Custom columns : 'Description' and other custom columns you add by clicking on 'Add column' will not have their data overwritten. These columns can be renamed by double-clicking or pressing F2 (Renaming a column will currently lose its data).", + "Custom columns : 'Description' and other custom columns you add by clicking on 'Add column' will not have their data overwritten. If a column name starts with '.' followed by a property name (e.g. '.Length'), it will be auto-populated with that property value. These columns can be renamed by double-clicking or pressing F2 (Renaming a column will currently lose its data).", ) + "\n" "\n"