diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp index 22ff0efa42..129b61e747 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-License-Identifier: LGPL-2.1-or-later /**************************************************************************** * * * Copyright (c) 2023 Ondsel * @@ -642,24 +642,8 @@ bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection // In case of sub-assembly, the jointgroup would trigger the dragger. continue; } - if (onlySolids - && !(obj->isDerivedFrom() || obj->isDerivedFrom() - || obj->isDerivedFrom())) { - continue; - } - App::DocumentObject* part = - getMovingPartFromRef(assemblyPart, selRoot, subNamesStr); - if (!canDragObjectIn3d(part)) { - continue; - } - - auto* pPlc = - dynamic_cast(part->getPropertyByName("Placement")); - - MovingObject movingObj(part, pPlc->getValue(), selRoot, subNamesStr); - - docsToMove.emplace_back(movingObj); + collectMovableObjects(selRoot, subNamesStr, obj, onlySolids); } } } @@ -690,9 +674,8 @@ bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection Gui::Selection().clearSelection(); docsToMove.clear(); } - MovingObject movingObj(obj, pPlc->getValue(), selRoot, sub); - docsToMove.emplace_back(movingObj); + docsToMove.emplace_back(obj, pPlc->getValue(), selRoot, sub); } } } @@ -700,6 +683,44 @@ bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection return !docsToMove.empty(); } +void ViewProviderAssembly::collectMovableObjects(App::DocumentObject* selRoot, + const std::string& subNamePrefix, + App::DocumentObject* currentObject, + bool onlySolids) +{ + // Get the AssemblyObject for context + auto* assemblyPart = getObject(); + + // Handling of special case: flexible AssemblyLink + auto* asmLink = dynamic_cast(currentObject); + if (asmLink && !asmLink->isRigid()) { + std::vector children = asmLink->Group.getValues(); + for (auto* child : children) { + // Recurse on children, appending the child's name to the subName prefix + std::string newSubNamePrefix = subNamePrefix + child->getNameInDocument() + "."; + collectMovableObjects(selRoot, newSubNamePrefix, child, onlySolids); + } + return; + } + + // Base case: This is not a flexible link, process it as a potential movable part. + if (onlySolids + && !(currentObject->isDerivedFrom() + || currentObject->isDerivedFrom() + || currentObject->isDerivedFrom())) { + return; + } + + App::DocumentObject* part = getMovingPartFromRef(assemblyPart, selRoot, subNamePrefix); + + if (canDragObjectIn3d(part)) { + auto* pPlc = dynamic_cast(part->getPropertyByName("Placement")); + if (pPlc) { + docsToMove.emplace_back(part, pPlc->getValue(), selRoot, subNamePrefix); + } + } +} + ViewProviderAssembly::DragMode ViewProviderAssembly::findDragMode() { auto addPartsToMove = [&](const std::vector& refs) { diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.h b/src/Mod/Assembly/Gui/ViewProviderAssembly.h index 3f99972dc4..9e37913a57 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.h +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.h @@ -51,13 +51,13 @@ struct MovingObject Base::Placement plc; App::PropertyXLinkSub* ref; App::DocumentObject* rootObj; // object of the selection object - std::string sub; // sub name given by the selection. + const std::string sub; // sub name given by the selection. // Constructor MovingObject(App::DocumentObject* o, const Base::Placement& p, App::DocumentObject* ro, - std::string& s) + const std::string& s) : obj(o) , plc(p) , ref(nullptr) @@ -230,6 +230,11 @@ public: private: bool tryMouseMove(const SbVec2s& cursorPos, Gui::View3DInventorViewer* viewer); void tryInitMove(const SbVec2s& cursorPos, Gui::View3DInventorViewer* viewer); + + void collectMovableObjects(App::DocumentObject* selRoot, + const std::string& subNamePrefix, + App::DocumentObject* currentObject, + bool onlySolids); }; } // namespace AssemblyGui