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"