Assembly: Enable ungrounded connected parts to move as one item.

This commit is contained in:
PaddleStroke
2024-08-05 08:21:08 +02:00
committed by Yorik van Havre
parent 8fb3b26704
commit 79b9d45726
5 changed files with 131 additions and 64 deletions

View File

@@ -454,9 +454,9 @@ App::DocumentObject* AssemblyObject::getJointOfPartConnectingToGround(App::Docum
return nullptr;
}
JointGroup* AssemblyObject::getJointGroup()
JointGroup* AssemblyObject::getJointGroup(App::Part* part)
{
App::Document* doc = getDocument();
App::Document* doc = part->getDocument();
std::vector<DocumentObject*> jointGroups =
doc->getObjectsOfType(Assembly::JointGroup::getClassTypeId());
@@ -464,13 +464,18 @@ JointGroup* AssemblyObject::getJointGroup()
return nullptr;
}
for (auto jointGroup : jointGroups) {
if (hasObject(jointGroup)) {
if (part->hasObject(jointGroup)) {
return dynamic_cast<JointGroup*>(jointGroup);
}
}
return nullptr;
}
JointGroup* AssemblyObject::getJointGroup()
{
return getJointGroup(this);
}
ViewGroup* AssemblyObject::getExplodedViewGroup()
{
App::Document* doc = getDocument();
@@ -487,7 +492,8 @@ ViewGroup* AssemblyObject::getExplodedViewGroup()
return nullptr;
}
std::vector<App::DocumentObject*> AssemblyObject::getJoints(bool updateJCS, bool delBadJoints)
std::vector<App::DocumentObject*>
AssemblyObject::getJoints(bool updateJCS, bool delBadJoints, bool subJoints)
{
std::vector<App::DocumentObject*> joints = {};
@@ -528,9 +534,11 @@ std::vector<App::DocumentObject*> AssemblyObject::getJoints(bool updateJCS, bool
}
// add sub assemblies joints.
for (auto& assembly : getSubAssemblies()) {
auto subJoints = assembly->getJoints(updateJCS, delBadJoints);
joints.insert(joints.end(), subJoints.begin(), subJoints.end());
if (subJoints) {
for (auto& assembly : getSubAssemblies()) {
auto subJoints = assembly->getJoints();
joints.insert(joints.end(), subJoints.begin(), subJoints.end());
}
}
// Make sure the joints are up to date.
@@ -1518,8 +1526,11 @@ std::vector<ObjRef> AssemblyObject::getDownstreamParts(App::DocumentObject* part
App::DocumentObject* joint)
{
// First we deactivate the joint
bool state = getJointActivated(joint);
setJointActivated(joint, false);
bool state = false;
if (joint) {
state = getJointActivated(joint);
setJointActivated(joint, false);
}
std::vector<App::DocumentObject*> joints = getJoints(false);
@@ -1533,7 +1544,9 @@ std::vector<ObjRef> AssemblyObject::getDownstreamParts(App::DocumentObject* part
}
}
AssemblyObject::setJointActivated(joint, state);
if (joint) {
AssemblyObject::setJointActivated(joint, state);
}
/*if (limit > 1000) { // Infinite loop protection
return {};
}
@@ -2177,14 +2190,15 @@ App::DocumentObject* AssemblyObject::getObjFromProp(App::DocumentObject* joint,
return propObj->getValue();
}
App::DocumentObject* AssemblyObject::getObjFromRef(App::PropertyXLinkSub* prop)
App::DocumentObject* AssemblyObject::getObjFromRef(App::DocumentObject* obj, std::string& sub)
{
if (!prop) {
if (!obj) {
return nullptr;
}
App::Document* doc = prop->getValue()->getDocument();
std::vector<std::string> names = getSubAsList(prop);
App::Document* doc = obj->getDocument();
std::vector<std::string> names = splitSubName(sub);
// Lambda function to check if the typeId is a BodySubObject
auto isBodySubObject = [](App::DocumentObject* obj) -> bool {
@@ -2217,6 +2231,10 @@ App::DocumentObject* AssemblyObject::getObjFromRef(App::PropertyXLinkSub* prop)
return nullptr;
}
if (obj->isDerivedFrom<App::DocumentObjectGroup>()) {
continue;
}
// The last but one name should be the selected
if (std::next(it) == std::prev(names.end())) {
return obj;
@@ -2251,6 +2269,25 @@ App::DocumentObject* AssemblyObject::getObjFromRef(App::PropertyXLinkSub* prop)
return nullptr;
}
App::DocumentObject* AssemblyObject::getObjFromRef(App::PropertyXLinkSub* prop)
{
if (!prop) {
return nullptr;
}
App::DocumentObject* obj = prop->getValue();
if (!obj) {
return nullptr;
}
std::vector<std::string> subs = prop->getSubValues();
if (subs.empty()) {
return nullptr;
}
return getObjFromRef(obj, subs[0]);
}
App::DocumentObject* AssemblyObject::getObjFromRef(App::DocumentObject* joint, const char* pName)
{
auto* prop = dynamic_cast<App::PropertyXLinkSub*>(joint->getPropertyByName(pName));

View File

@@ -168,8 +168,8 @@ public:
Base::Placement getMbdPlacement(std::shared_ptr<MbD::ASMTPart> mbdPart);
bool validateNewPlacements();
void setNewPlacements();
void recomputeJointPlacements(std::vector<App::DocumentObject*> joints);
void redrawJointPlacements(std::vector<App::DocumentObject*> joints);
static void recomputeJointPlacements(std::vector<App::DocumentObject*> joints);
static void redrawJointPlacements(std::vector<App::DocumentObject*> joints);
// Ondsel Solver interface
@@ -193,7 +193,8 @@ public:
void jointParts(std::vector<App::DocumentObject*> joints);
JointGroup* getJointGroup();
ViewGroup* getExplodedViewGroup();
std::vector<App::DocumentObject*> getJoints(bool updateJCS = true, bool delBadJoints = false);
std::vector<App::DocumentObject*>
getJoints(bool updateJCS = true, bool delBadJoints = false, bool subJoints = true);
std::vector<App::DocumentObject*> getGroundedJoints();
std::vector<App::DocumentObject*> getJointsOfObj(App::DocumentObject* obj);
std::vector<App::DocumentObject*> getJointsOfPart(App::DocumentObject* part);
@@ -217,7 +218,8 @@ public:
bool isPartGrounded(App::DocumentObject* part);
bool isPartConnected(App::DocumentObject* part);
std::vector<ObjRef> getDownstreamParts(App::DocumentObject* part, App::DocumentObject* joint);
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,
@@ -255,6 +257,8 @@ public:
static DistanceType getDistanceType(App::DocumentObject* joint);
static JointGroup* getJointGroup(App::Part* part);
// getters to get from properties
static void setJointActivated(App::DocumentObject* joint, bool val);
static bool getJointActivated(App::DocumentObject* joint);
@@ -264,6 +268,7 @@ public:
static std::string getElementFromProp(App::DocumentObject* obj, const char* propName);
static std::string getElementTypeFromProp(App::DocumentObject* obj, const char* propName);
static App::DocumentObject* getObjFromProp(App::DocumentObject* joint, const char* propName);
static App::DocumentObject* getObjFromRef(App::DocumentObject* obj, std::string& sub);
static App::DocumentObject* getObjFromRef(App::PropertyXLinkSub* prop);
static App::DocumentObject* getObjFromRef(App::DocumentObject* joint, const char* propName);
App::DocumentObject* getMovingPartFromRef(App::DocumentObject* obj, std::string& sub);

View File

@@ -1,23 +1,24 @@
/***************************************************************************
* Copyright (c) 2014 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2024 Ondsel <development@ondsel.com> *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/