diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index f219bb751a..6b47a6d70e 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -559,8 +559,10 @@ std::shared_ptr AssemblyObject::makeMbdAssembly() return assembly; } -App::DocumentObject* AssemblyObject::getJointOfPartConnectingToGround(App::DocumentObject* part, - std::string& name) +App::DocumentObject* AssemblyObject::getJointOfPartConnectingToGround( + App::DocumentObject* part, + std::string& name, + const std::vector& excludeJoints) { if (!part) { return nullptr; @@ -572,6 +574,11 @@ App::DocumentObject* AssemblyObject::getJointOfPartConnectingToGround(App::Docum if (!joint) { continue; } + + if (std::ranges::find(excludeJoints, joint) != excludeJoints.end()) { + continue; + } + App::DocumentObject* part1 = getMovingPartFromRef(this, joint, "Reference1"); App::DocumentObject* part2 = getMovingPartFromRef(this, joint, "Reference2"); if (!part1 || !part2) { @@ -1882,43 +1889,19 @@ std::vector AssemblyObject::getDownstreamParts(App::DocumentObject* part return downstreamParts; } -std::vector AssemblyObject::getUpstreamParts(App::DocumentObject* part, - int limit) -{ - if (!part) { - return {}; - } - - if (limit > 1000) { // Infinite loop protection - return {}; - } - limit++; - - if (isPartGrounded(part)) { - return {part}; - } - - std::string name; - App::DocumentObject* connectingJoint = getJointOfPartConnectingToGround(part, name); - App::DocumentObject* upPart = - getMovingPartFromRef(this, - connectingJoint, - name == "Reference1" ? "Reference2" : "Reference1"); - - std::vector upstreamParts = getUpstreamParts(upPart, limit); - upstreamParts.push_back(part); - return upstreamParts; -} - -App::DocumentObject* AssemblyObject::getUpstreamMovingPart(App::DocumentObject* part, - App::DocumentObject*& joint, - std::string& name) +App::DocumentObject* +AssemblyObject::getUpstreamMovingPart(App::DocumentObject* part, + App::DocumentObject*& joint, + std::string& name, + std::vector excludeJoints) { if (!part || isPartGrounded(part)) { return nullptr; } - joint = getJointOfPartConnectingToGround(part, name); + excludeJoints.push_back(joint); + + joint = getJointOfPartConnectingToGround(part, name, excludeJoints); JointType jointType = getJointType(joint); if (jointType != JointType::Fixed) { return part; diff --git a/src/Mod/Assembly/App/AssemblyObject.h b/src/Mod/Assembly/App/AssemblyObject.h index af63b31e1c..59689fd708 100644 --- a/src/Mod/Assembly/App/AssemblyObject.h +++ b/src/Mod/Assembly/App/AssemblyObject.h @@ -154,8 +154,10 @@ public: std::vector getGroundedJoints(); std::vector getJointsOfObj(App::DocumentObject* obj); std::vector getJointsOfPart(App::DocumentObject* part); - App::DocumentObject* getJointOfPartConnectingToGround(App::DocumentObject* part, - std::string& name); + App::DocumentObject* + getJointOfPartConnectingToGround(App::DocumentObject* part, + std::string& name, + const std::vector& excludeJoints = {}); std::unordered_set getGroundedParts(); std::unordered_set fixGroundedParts(); void fixGroundedPart(App::DocumentObject* obj, Base::Placement& plc, std::string& jointName); @@ -176,10 +178,11 @@ public: std::vector getDownstreamParts(App::DocumentObject* part, App::DocumentObject* joint = nullptr); - std::vector getUpstreamParts(App::DocumentObject* part, int limit = 0); - App::DocumentObject* getUpstreamMovingPart(App::DocumentObject* part, - App::DocumentObject*& joint, - std::string& name); + App::DocumentObject* + getUpstreamMovingPart(App::DocumentObject* part, + App::DocumentObject*& joint, + std::string& name, + std::vector excludeJoints = {}); double getObjMass(App::DocumentObject* obj); void setObjMasses(std::vector> objectMasses); diff --git a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp index 01820f0bd1..20624ed245 100644 --- a/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderAssembly.cpp @@ -763,6 +763,8 @@ ViewProviderAssembly::DragMode ViewProviderAssembly::findDragMode() // If fixed joint we need to find the upstream joint to find move mode. // For example : Gnd -(revolute)- A -(fixed)- B : if user try to move B, then we should // actually move A + movingJoint = nullptr; // reinitialize because getUpstreamMovingPart will call + // getJointOfPartConnectingToGround again which will find the same joint. auto* upPart = assemblyPart->getUpstreamMovingPart(docsToMove[0].obj, movingJoint, pName); if (!movingJoint) {