diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index 7978b353a0..84ad387cf7 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -800,7 +800,7 @@ AssemblyObject::getConnectedParts(App::DocumentObject* part, bool AssemblyObject::isPartGrounded(App::DocumentObject* obj) { - std::vector groundedObjs = fixGroundedParts(); + std::vector groundedObjs = getGroundedParts(); for (auto* groundedObj : groundedObjs) { if (groundedObj->getFullName() == obj->getFullName()) { diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp index 571ed523f4..a780ea3ccb 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp @@ -458,6 +458,38 @@ bool ViewProviderAssembly::mouseButtonPressed(int Button, return false; } +bool ViewProviderAssembly::canDragObjectIn3d(App::DocumentObject* obj) const +{ + if (!obj) { + return false; + } + + auto* assemblyPart = static_cast(getObject()); + + // Check if the selected object is a child of the assembly + if (!assemblyPart->hasObject(obj, true)) { + return false; + } + + auto* propPlacement = + dynamic_cast(obj->getPropertyByName("Placement")); + if (!propPlacement) { + return false; + } + + // We have to exclude Grounded joints as they happen to have a Placement prop + auto* propLink = dynamic_cast(obj->getPropertyByName("ObjectToGround")); + if (propLink) { + return false; + } + + // We have to exclude grounded objects as they should not move. + if (assemblyPart->isPartGrounded(obj)) { + return false; + } + return true; +} + bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection, bool onlySolids) { // check the current selection, and check if any of the selected objects are within this @@ -467,7 +499,7 @@ bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection docsToMove.clear(); // Get the assembly object for this ViewProvider - AssemblyObject* assemblyPart = static_cast(getObject()); + auto* assemblyPart = static_cast(getObject()); if (!assemblyPart) { return false; @@ -490,26 +522,13 @@ bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection } App::DocumentObject* obj = getObjectFromSubNames(subNames); - if (!obj) { + + if (!canDragObjectIn3d(obj)) { continue; } - // Check if the selected object is a child of the assembly - if (assemblyPart->hasObject(obj, true)) { - auto* propPlacement = - dynamic_cast(obj->getPropertyByName("Placement")); - if (!propPlacement) { - continue; - } - // We have to exclude Grounded joints as they happen to have a Placement prop - auto* propLink = - dynamic_cast(obj->getPropertyByName("ObjectToGround")); - if (propLink) { - continue; - } - - docsToMove.emplace_back(obj, propPlacement->getValue()); - } + auto* pPlc = dynamic_cast(obj->getPropertyByName("Placement")); + docsToMove.emplace_back(obj, pPlc->getValue()); } } @@ -523,32 +542,26 @@ bool ViewProviderAssembly::getSelectedObjectsWithinAssembly(bool addPreselection std::string subNamesStr = Gui::Selection().getPreselection().pSubName; std::vector subNames = parseSubNames(subNamesStr); - App::DocumentObject* preselectedObj = getObjectFromSubNames(subNames); - if (preselectedObj && assemblyPart->hasObject(preselectedObj, true)) { + App::DocumentObject* obj = getObjectFromSubNames(subNames); + if (canDragObjectIn3d(obj)) { + bool alreadyIn = false; for (auto& pair : docsToMove) { - App::DocumentObject* obj = pair.first; - if (obj == preselectedObj) { + App::DocumentObject* obji = pair.first; + if (obji == obj) { alreadyIn = true; break; } } if (!alreadyIn) { - auto* propPlacement = dynamic_cast( - preselectedObj->getPropertyByName("Placement")); - if (propPlacement) { - // We have to exclude Grounded joints as they happen to have a Placement prop - auto* propLink = dynamic_cast( - preselectedObj->getPropertyByName("ObjectToGround")); - if (!propLink) { - if (!ctrlPressed) { - Gui::Selection().clearSelection(); - docsToMove.clear(); - } - docsToMove.emplace_back(preselectedObj, propPlacement->getValue()); - } + auto* pPlc = + dynamic_cast(obj->getPropertyByName("Placement")); + if (!ctrlPressed) { + Gui::Selection().clearSelection(); + docsToMove.clear(); } + docsToMove.emplace_back(obj, pPlc->getValue()); } } } diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.h b/src/Mod/Assembly/Gui/ViewProviderAssembly.h index ab28415a6d..e952b1c91a 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.h +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.h @@ -116,6 +116,7 @@ public: } + bool canDragObjectIn3d(App::DocumentObject* obj) const; bool getSelectedObjectsWithinAssembly(bool addPreselection = true, bool onlySolids = false); App::DocumentObject* getObjectFromSubNames(std::vector& subNames); std::vector parseSubNames(std::string& subNamesStr);