* Assembly: Fix infinite loop with subassembly. Fix #19319 * squash * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update AssemblyObject.h * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -559,8 +559,10 @@ std::shared_ptr<ASMTAssembly> 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<App::DocumentObject*>& 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<ObjRef> AssemblyObject::getDownstreamParts(App::DocumentObject* part
|
||||
return downstreamParts;
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> 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<App::DocumentObject*> 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<App::DocumentObject*> 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;
|
||||
|
||||
@@ -154,8 +154,10 @@ public:
|
||||
std::vector<App::DocumentObject*> getGroundedJoints();
|
||||
std::vector<App::DocumentObject*> getJointsOfObj(App::DocumentObject* obj);
|
||||
std::vector<App::DocumentObject*> 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<App::DocumentObject*>& excludeJoints = {});
|
||||
std::unordered_set<App::DocumentObject*> getGroundedParts();
|
||||
std::unordered_set<App::DocumentObject*> fixGroundedParts();
|
||||
void fixGroundedPart(App::DocumentObject* obj, Base::Placement& plc, std::string& jointName);
|
||||
@@ -176,10 +178,11 @@ public:
|
||||
|
||||
std::vector<ObjRef> getDownstreamParts(App::DocumentObject* part,
|
||||
App::DocumentObject* joint = nullptr);
|
||||
std::vector<App::DocumentObject*> 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<App::DocumentObject*> excludeJoints = {});
|
||||
|
||||
double getObjMass(App::DocumentObject* obj);
|
||||
void setObjMasses(std::vector<std::pair<App::DocumentObject*, double>> objectMasses);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user