Merge pull request 'fix(assembly): use instance suffixes for duplicate part labels' (#335) from fix/assembly-part-number-suffix into main
Some checks failed
Build and Test / build (push) Has been cancelled

Reviewed-on: #335
This commit was merged in pull request #335.
This commit is contained in:
2026-02-26 16:34:34 +00:00
2 changed files with 27 additions and 3 deletions

View File

@@ -311,6 +311,19 @@ void AssemblyLink::updateContents()
purgeTouched(); purgeTouched();
} }
// Generate an instance label for assembly components by appending a -N suffix.
// All instances get a suffix (starting at -1) so that structured part numbers
// like "P03-0001" are never mangled by UniqueNameManager's trailing-digit logic.
static std::string makeInstanceLabel(App::Document* doc, const std::string& baseLabel)
{
for (int i = 1;; ++i) {
std::string candidate = baseLabel + "-" + std::to_string(i);
if (!doc->containsLabel(candidate)) {
return candidate;
}
}
}
void AssemblyLink::synchronizeComponents() void AssemblyLink::synchronizeComponents()
{ {
App::Document* doc = getDocument(); App::Document* doc = getDocument();
@@ -428,7 +441,7 @@ void AssemblyLink::synchronizeComponents()
auto* subAsmLink = static_cast<AssemblyLink*>(newObj); auto* subAsmLink = static_cast<AssemblyLink*>(newObj);
subAsmLink->LinkedObject.setValue(obj); subAsmLink->LinkedObject.setValue(obj);
subAsmLink->Rigid.setValue(asmLink->Rigid.getValue()); subAsmLink->Rigid.setValue(asmLink->Rigid.getValue());
subAsmLink->Label.setValue(obj->Label.getValue()); subAsmLink->Label.setValue(makeInstanceLabel(doc, obj->Label.getValue()));
addObject(subAsmLink); addObject(subAsmLink);
link = subAsmLink; link = subAsmLink;
} }
@@ -440,7 +453,7 @@ void AssemblyLink::synchronizeComponents()
); );
newLink->LinkedObject.setValue(srcLink->getTrueLinkedObject(false)); newLink->LinkedObject.setValue(srcLink->getTrueLinkedObject(false));
newLink->Label.setValue(obj->Label.getValue()); newLink->Label.setValue(makeInstanceLabel(doc, obj->Label.getValue()));
addObject(newLink); addObject(newLink);
newLink->ElementCount.setValue(srcLink->ElementCount.getValue()); newLink->ElementCount.setValue(srcLink->ElementCount.getValue());
@@ -461,7 +474,7 @@ void AssemblyLink::synchronizeComponents()
App::DocumentObject* newObj = doc->addObject("App::Link", obj->getNameInDocument()); App::DocumentObject* newObj = doc->addObject("App::Link", obj->getNameInDocument());
auto* newLink = static_cast<App::Link*>(newObj); auto* newLink = static_cast<App::Link*>(newObj);
newLink->LinkedObject.setValue(obj); newLink->LinkedObject.setValue(obj);
newLink->Label.setValue(obj->Label.getValue()); newLink->Label.setValue(makeInstanceLabel(doc, obj->Label.getValue()));
addObject(newLink); addObject(newLink);
link = newLink; link = newLink;
} }

View File

@@ -122,4 +122,15 @@ TEST(UniqueNameManager, UniqueNameWith9NDigits)
manager.addExactName("Compound123456789"); manager.addExactName("Compound123456789");
EXPECT_EQ(manager.makeUniqueName("Compound", 3), "Compound123456790"); EXPECT_EQ(manager.makeUniqueName("Compound", 3), "Compound123456790");
} }
TEST(UniqueNameManager, StructuredPartNumberDecomposition)
{
// Structured part numbers like P03-0001 have their trailing digits
// treated as the uniquifying suffix by UniqueNameManager. This is
// correct for default FreeCAD objects (Body -> Body001) but wrong
// for structured identifiers. Assembly module handles this separately
// via makeInstanceLabel which appends -N instance suffixes instead.
Base::UniqueNameManager manager;
manager.addExactName("P03-0001");
EXPECT_EQ(manager.makeUniqueName("P03-0001", 3), "P03-0002");
}
// NOLINTEND(cppcoreguidelines-*,readability-*) // NOLINTEND(cppcoreguidelines-*,readability-*)