Assembly: BOM: take mirrored state of links in account. (#26113)
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include <App/PropertyPythonObject.h>
|
||||
#include <App/Range.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Placement.h>
|
||||
#include <Base/Rotation.h>
|
||||
#include <Base/Tools.h>
|
||||
@@ -144,9 +145,15 @@ void BomObject::generateBOM()
|
||||
saveCustomColumnData();
|
||||
clearAll();
|
||||
obj_list.clear();
|
||||
obj_mirrored_list.clear();
|
||||
size_t row = 0;
|
||||
size_t col = 0;
|
||||
|
||||
auto hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Assembly"
|
||||
);
|
||||
mirroredSuffix = hGrp->GetASCII("BomMirroredSuffix", " (mirrored)");
|
||||
|
||||
// Populate headers
|
||||
for (auto& columnName : columnsNames.getValues()) {
|
||||
setCell(App::CellAddress(row, col), columnName.c_str());
|
||||
@@ -184,6 +191,9 @@ void BomObject::addObjectChildrenToBom(
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isMirrored = isObjMirrored(child);
|
||||
|
||||
if (auto* asmLink = freecad_cast<AssemblyLink*>(child)) {
|
||||
child = asmLink->getLinkedAssembly();
|
||||
if (!child) {
|
||||
@@ -206,10 +216,14 @@ void BomObject::addObjectChildrenToBom(
|
||||
// Check if the object is not already in (case of links). And if so just increment.
|
||||
// Note: an object can be used in several parts. In which case we do no want to blindly
|
||||
// increment.
|
||||
// We also check if the Mirror state matches. Mirrored parts should not group with
|
||||
// non-mirrored parts.
|
||||
bool found = false;
|
||||
for (size_t i = siblingsInitialRow; i <= row; ++i) {
|
||||
size_t idInList = i - 1; // -1 for the header
|
||||
if (idInList < obj_list.size() && child == obj_list[idInList]) {
|
||||
if (idInList < obj_list.size() && child == obj_list[idInList]
|
||||
&& idInList < obj_mirrored_list.size()
|
||||
&& isMirrored == obj_mirrored_list[idInList]) {
|
||||
|
||||
int qty = std::stoi(getText(i, quantityColIndex)) + 1;
|
||||
setCell(App::CellAddress(i, quantityColIndex), std::to_string(qty).c_str());
|
||||
@@ -225,7 +239,7 @@ void BomObject::addObjectChildrenToBom(
|
||||
std::string sub_index = index + std::to_string(sub_i);
|
||||
++sub_i;
|
||||
|
||||
addObjectToBom(child, row, sub_index);
|
||||
addObjectToBom(child, row, sub_index, isMirrored);
|
||||
++row;
|
||||
|
||||
if ((child->isDerivedFrom<AssemblyObject>() && detailSubAssemblies.getValue())
|
||||
@@ -236,7 +250,26 @@ void BomObject::addObjectChildrenToBom(
|
||||
}
|
||||
}
|
||||
|
||||
void BomObject::addObjectToBom(App::DocumentObject* obj, size_t row, std::string index)
|
||||
bool BomObject::isObjMirrored(App::DocumentObject* obj)
|
||||
{
|
||||
// Determine mirror state based on Scale properties.
|
||||
// We multiply scales to handle nested mirroring (e.g., Mirrored LinkElement inside Mirrored
|
||||
// LinkGroup = Normal).
|
||||
double accumulatedScale = 1.0;
|
||||
if (auto element = static_cast<App::LinkElement*>(obj)) {
|
||||
accumulatedScale *= element->Scale.getValue();
|
||||
|
||||
if (auto group = element->getLinkGroup()) {
|
||||
accumulatedScale *= group->Scale.getValue();
|
||||
}
|
||||
}
|
||||
else if (auto link = static_cast<App::Link*>(obj)) {
|
||||
accumulatedScale *= link->Scale.getValue();
|
||||
}
|
||||
return accumulatedScale < 0.0;
|
||||
}
|
||||
|
||||
void BomObject::addObjectToBom(App::DocumentObject* obj, size_t row, std::string index, bool isMirrored)
|
||||
{
|
||||
obj_list.push_back(obj);
|
||||
size_t col = 0;
|
||||
@@ -245,7 +278,17 @@ void BomObject::addObjectToBom(App::DocumentObject* obj, size_t row, std::string
|
||||
setCell(App::CellAddress(row, col), (std::string("'") + index).c_str());
|
||||
}
|
||||
else if (columnName == "Name") {
|
||||
setCell(App::CellAddress(row, col), obj->Label.getValue());
|
||||
std::string name = obj->Label.getValue();
|
||||
// Distinctly label mirrored parts so they are identifiable in the BOM
|
||||
if (isMirrored) {
|
||||
if (auto* linkedObj = obj->getLinkedObject()) {
|
||||
// We add a suffix only if the label is the same.
|
||||
if (name == linkedObj->Label.getValue()) {
|
||||
name += mirroredSuffix;
|
||||
}
|
||||
}
|
||||
}
|
||||
setCell(App::CellAddress(row, col), name.c_str());
|
||||
}
|
||||
else if (columnName == "File Name") {
|
||||
setCell(App::CellAddress(row, col), obj->getDocument()->getFileName());
|
||||
|
||||
@@ -76,9 +76,10 @@ public:
|
||||
App::DocumentObjectExecReturn* execute() override;
|
||||
|
||||
void generateBOM();
|
||||
void addObjectToBom(App::DocumentObject* obj, size_t row, std::string index);
|
||||
void addObjectToBom(App::DocumentObject* obj, size_t row, std::string index, bool isMirrored = false);
|
||||
void addObjectChildrenToBom(std::vector<App::DocumentObject*> objs, size_t& row, std::string index);
|
||||
void saveCustomColumnData();
|
||||
bool isObjMirrored(App::DocumentObject* obj);
|
||||
|
||||
AssemblyObject* getAssembly() const;
|
||||
|
||||
@@ -93,9 +94,12 @@ public:
|
||||
|
||||
std::vector<BomDataElement> dataElements;
|
||||
std::vector<App::DocumentObject*> obj_list;
|
||||
std::vector<bool> obj_mirrored_list;
|
||||
|
||||
private:
|
||||
std::string getBomPropertyValue(App::DocumentObject* obj, const std::string& baseName);
|
||||
|
||||
std::string mirroredSuffix;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user