Assembly: fix sub assembly joint bug (#27172)

This commit is contained in:
PaddleStroke
2026-01-26 19:23:07 +01:00
committed by GitHub
parent 1446a91bdc
commit caff52b1ed
2 changed files with 74 additions and 0 deletions

View File

@@ -225,6 +225,79 @@ void AssemblyLink::onChanged(const App::Property* prop)
App::Part::onChanged(prop);
}
void AssemblyLink::updateParentJoints()
{
AssemblyObject* parent = getParentAssembly();
if (!parent) {
return;
}
bool rigid = Rigid.getValue();
// Iterate joints in the immediate parent assembly only (recursive=false)
for (auto* joint : parent->getJoints(false, false, false)) {
for (const char* refName : {"Reference1", "Reference2"}) {
auto* prop = dynamic_cast<App::PropertyXLinkSub*>(joint->getPropertyByName(refName));
if (!prop) {
continue;
}
App::DocumentObject* refObj = prop->getValue();
if (!refObj) {
continue;
}
if (rigid) { // Flexible -> Rigid
if (hasObject(refObj)) {
// The joint currently points to a child (refObj) inside this AssemblyLink.
// We must repoint it to 'this' and prepend the child's name to the sub-elements.
std::vector<std::string> subs = prop->getSubValues();
std::vector<std::string> newSubs;
std::string prefix = refObj->getNameInDocument();
prefix += ".";
for (const auto& s : subs) {
newSubs.push_back(prefix + s);
}
prop->setValue(this);
prop->setSubValues(std::move(newSubs));
}
}
else { // Rigid -> Flexible
if (refObj == this) {
// The joint currently points to 'this'.
// We must extract the child's name from the sub-element, point to the child,
// and strip the prefix.
std::vector<std::string> subs = prop->getSubValues();
if (subs.empty()) {
continue;
}
std::vector<std::string> parts = Base::Tools::splitSubName(subs[0]);
if (parts.empty()) {
continue;
}
std::string childName = parts[0];
App::DocumentObject* child = getDocument()->getObject(childName.c_str());
if (child && hasObject(child)) {
std::vector<std::string> newSubs;
size_t prefixLen = childName.length() + 1; // "Name."
for (const auto& s : subs) {
if (s.length() >= prefixLen) {
newSubs.push_back(s.substr(prefixLen));
}
else {
newSubs.push_back(s);
}
}
prop->setValue(child);
prop->setSubValues(std::move(newSubs));
}
}
}
}
if (joint->isTouched()) {
joint->recomputeFeature();
}
}
}
void AssemblyLink::updateContents()
{
synchronizeComponents();

View File

@@ -72,6 +72,7 @@ public:
* Update all of the components and joints from the Assembly
*/
void updateContents();
void updateParentJoints();
void synchronizeComponents();
void synchronizeJoints();