Assembly: Change Object1/2 from strings to PropertyXLinkSub and Remove Element1/2 and Vertex1/2

This commit is contained in:
PaddleStroke
2024-06-10 18:45:00 +02:00
committed by Chris Hennes
parent e38259c307
commit f5a6e0fd32
6 changed files with 201 additions and 237 deletions

View File

@@ -434,8 +434,8 @@ App::DocumentObject* AssemblyObject::getJointOfPartConnectingToGround(App::Docum
if (!joint) {
continue;
}
App::DocumentObject* part1 = getLinkObjFromProp(joint, "Part1");
App::DocumentObject* part2 = getLinkObjFromProp(joint, "Part2");
App::DocumentObject* part1 = getObjFromProp(joint, "Part1");
App::DocumentObject* part2 = getObjFromProp(joint, "Part2");
if (!part1 || !part2) {
continue;
}
@@ -507,8 +507,8 @@ std::vector<App::DocumentObject*> AssemblyObject::getJoints(bool updateJCS, bool
continue;
}
auto* part1 = getLinkObjFromProp(joint, "Part1");
auto* part2 = getLinkObjFromProp(joint, "Part2");
auto* part1 = getObjFromProp(joint, "Part1");
auto* part2 = getObjFromProp(joint, "Part2");
if (!part1 || !part2 || part1->getFullName() == part2->getFullName()) {
// Remove incomplete joints. Left-over when the user delets a part.
// Remove incoherent joints (self-pointing joints)
@@ -571,8 +571,8 @@ std::vector<App::DocumentObject*> AssemblyObject::getJointsOfObj(App::DocumentOb
std::vector<App::DocumentObject*> jointsOf;
for (auto joint : joints) {
App::DocumentObject* obj1 = getObjFromNameProp(joint, "object1", "Part1");
App::DocumentObject* obj2 = getObjFromNameProp(joint, "Object2", "Part2");
App::DocumentObject* obj1 = getObjFromProp(joint, "object1");
App::DocumentObject* obj2 = getObjFromProp(joint, "Object2");
if (obj == obj1 || obj == obj2) {
jointsOf.push_back(obj);
}
@@ -587,8 +587,8 @@ std::vector<App::DocumentObject*> AssemblyObject::getJointsOfPart(App::DocumentO
std::vector<App::DocumentObject*> jointsOf;
for (auto joint : joints) {
App::DocumentObject* part1 = getLinkObjFromProp(joint, "Part1");
App::DocumentObject* part2 = getLinkObjFromProp(joint, "Part2");
App::DocumentObject* part1 = getObjFromProp(joint, "Part1");
App::DocumentObject* part2 = getObjFromProp(joint, "Part2");
if (part == part1 || part == part2) {
jointsOf.push_back(joint);
}
@@ -748,8 +748,8 @@ void AssemblyObject::removeUnconnectedJoints(std::vector<App::DocumentObject*>&
joints.begin(),
joints.end(),
[&connectedParts](App::DocumentObject* joint) {
App::DocumentObject* obj1 = getLinkObjFromProp(joint, "Part1");
App::DocumentObject* obj2 = getLinkObjFromProp(joint, "Part2");
App::DocumentObject* obj1 = getObjFromProp(joint, "Part1");
App::DocumentObject* obj2 = getObjFromProp(joint, "Part2");
if ((connectedParts.find(obj1) == connectedParts.end())
|| (connectedParts.find(obj2) == connectedParts.end())) {
Base::Console().Warning(
@@ -786,8 +786,8 @@ AssemblyObject::getConnectedParts(App::DocumentObject* part,
continue;
}
App::DocumentObject* obj1 = getLinkObjFromProp(joint, "Part1");
App::DocumentObject* obj2 = getLinkObjFromProp(joint, "Part2");
App::DocumentObject* obj1 = getObjFromProp(joint, "Part1");
App::DocumentObject* obj2 = getObjFromProp(joint, "Part2");
if (obj1 == part) {
connectedParts.push_back(obj2);
}
@@ -928,10 +928,10 @@ std::shared_ptr<ASMTJoint> AssemblyObject::makeMbdJointDistance(App::DocumentObj
{
DistanceType type = getDistanceType(joint);
const char* elt1 = getElementFromProp(joint, "Element1");
const char* elt2 = getElementFromProp(joint, "Element2");
auto* obj1 = getLinkedObjFromNameProp(joint, "Object1", "Part1");
auto* obj2 = getLinkedObjFromNameProp(joint, "Object2", "Part2");
const char* elt1 = getElementFromProp(joint, "Object1");
const char* elt2 = getElementFromProp(joint, "Object2");
auto* obj1 = getLinkedObjFromProp(joint, "Object1");
auto* obj2 = getLinkedObjFromProp(joint, "Object2");
if (type == DistanceType::PointPoint) {
// Point to point distance, or ball joint if distance=0.
@@ -1250,8 +1250,8 @@ std::string AssemblyObject::handleOneSideOfJoint(App::DocumentObject* joint,
const char* propPartName,
const char* propPlcName)
{
App::DocumentObject* part = getLinkObjFromProp(joint, propPartName);
App::DocumentObject* obj = getObjFromNameProp(joint, propObjName, propPartName);
App::DocumentObject* part = getObjFromProp(joint, propPartName);
App::DocumentObject* obj = getObjFromProp(joint, propObjName);
if (!part || !obj) {
Base::Console().Warning("The property %s of Joint %s is empty.",
@@ -1302,12 +1302,12 @@ void AssemblyObject::getRackPinionMarkers(App::DocumentObject* joint,
swapJCS(joint); // make sure that rack is first.
}
App::DocumentObject* part1 = getLinkObjFromProp(joint, "Part1");
App::DocumentObject* obj1 = getObjFromNameProp(joint, "Object1", "Part1");
App::DocumentObject* part1 = getObjFromProp(joint, "Part1");
App::DocumentObject* obj1 = getObjFromProp(joint, "Object1");
Base::Placement plc1 = getPlacementFromProp(joint, "Placement1");
App::DocumentObject* part2 = getLinkObjFromProp(joint, "Part2");
App::DocumentObject* obj2 = getObjFromNameProp(joint, "Object2", "Part2");
App::DocumentObject* part2 = getObjFromProp(joint, "Part2");
App::DocumentObject* obj2 = getObjFromProp(joint, "Object2");
Base::Placement plc2 = getPlacementFromProp(joint, "Placement2");
if (!part1 || !obj1) {
@@ -1370,21 +1370,21 @@ void AssemblyObject::getRackPinionMarkers(App::DocumentObject* joint,
int AssemblyObject::slidingPartIndex(App::DocumentObject* joint)
{
App::DocumentObject* part1 = getLinkObjFromProp(joint, "Part1");
App::DocumentObject* obj1 = getObjFromNameProp(joint, "Object1", "Part1");
App::DocumentObject* part1 = getObjFromProp(joint, "Part1");
App::DocumentObject* obj1 = getObjFromProp(joint, "Object1");
boost::ignore_unused(obj1);
Base::Placement plc1 = getPlacementFromProp(joint, "Placement1");
App::DocumentObject* part2 = getLinkObjFromProp(joint, "Part2");
App::DocumentObject* obj2 = getObjFromNameProp(joint, "Object2", "Part2");
App::DocumentObject* part2 = getObjFromProp(joint, "Part2");
App::DocumentObject* obj2 = getObjFromProp(joint, "Object2");
boost::ignore_unused(obj2);
Base::Placement plc2 = getPlacementFromProp(joint, "Placement2");
int slidingFound = 0;
for (auto* jt : getJoints(false, false)) {
if (getJointType(jt) == JointType::Slider) {
App::DocumentObject* jpart1 = getLinkObjFromProp(jt, "Part1");
App::DocumentObject* jpart2 = getLinkObjFromProp(jt, "Part2");
App::DocumentObject* jpart1 = getObjFromProp(jt, "Part1");
App::DocumentObject* jpart2 = getObjFromProp(jt, "Part2");
int found = 0;
Base::Placement plcjt, plci;
if (jpart1 == part1 || jpart1 == part2) {
@@ -1527,8 +1527,8 @@ std::vector<App::DocumentObject*> AssemblyObject::getDownstreamParts(App::Docume
auto it = std::remove(jointsOfPart.begin(), jointsOfPart.end(), connectingJoint);
jointsOfPart.erase(it, jointsOfPart.end());
for (auto joint : jointsOfPart) {
App::DocumentObject* part1 = getLinkObjFromProp(joint, "Part1");
App::DocumentObject* part2 = getLinkObjFromProp(joint, "Part2");
App::DocumentObject* part1 = getObjFromProp(joint, "Part1");
App::DocumentObject* part2 = getObjFromProp(joint, "Part2");
bool firstIsDown = part->getFullName() == part2->getFullName();
App::DocumentObject* downstreamPart = firstIsDown ? part1 : part2;
@@ -1574,7 +1574,7 @@ std::vector<App::DocumentObject*> AssemblyObject::getUpstreamParts(App::Document
std::string name;
App::DocumentObject* connectingJoint = getJointOfPartConnectingToGround(part, name);
App::DocumentObject* upPart =
getLinkObjFromProp(connectingJoint, name == "Part1" ? "Part2" : "Part1");
getObjFromProp(connectingJoint, name == "Part1" ? "Part2" : "Part1");
std::vector<App::DocumentObject*> upstreamParts = getUpstreamParts(upPart, limit);
upstreamParts.push_back(part);
@@ -1595,7 +1595,7 @@ App::DocumentObject* AssemblyObject::getUpstreamMovingPart(App::DocumentObject*
}
App::DocumentObject* upPart =
getLinkObjFromProp(connectingJoint, name == "Part1" ? "Part2" : "Part1");
getObjFromProp(connectingJoint, name == "Part1" ? "Part2" : "Part1");
return getUpstreamMovingPart(upPart);
}
@@ -1659,20 +1659,6 @@ void AssemblyObject::updateGroundedJointsPlacements()
void AssemblyObject::swapJCS(App::DocumentObject* joint)
{
auto propElement1 = dynamic_cast<App::PropertyString*>(joint->getPropertyByName("Element1"));
auto propElement2 = dynamic_cast<App::PropertyString*>(joint->getPropertyByName("Element2"));
if (propElement1 && propElement2) {
auto temp = std::string(propElement1->getValue());
propElement1->setValue(propElement2->getValue());
propElement2->setValue(temp);
}
auto propVertex1 = dynamic_cast<App::PropertyString*>(joint->getPropertyByName("Vertex1"));
auto propVertex2 = dynamic_cast<App::PropertyString*>(joint->getPropertyByName("Vertex2"));
if (propVertex1 && propVertex2) {
auto temp = std::string(propVertex1->getValue());
propVertex1->setValue(propVertex2->getValue());
propVertex2->setValue(temp);
}
auto propPlacement1 =
dynamic_cast<App::PropertyPlacement*>(joint->getPropertyByName("Placement1"));
auto propPlacement2 =
@@ -1682,12 +1668,16 @@ void AssemblyObject::swapJCS(App::DocumentObject* joint)
propPlacement1->setValue(propPlacement2->getValue());
propPlacement2->setValue(temp);
}
auto propObject1 = dynamic_cast<App::PropertyString*>(joint->getPropertyByName("Object1"));
auto propObject2 = dynamic_cast<App::PropertyString*>(joint->getPropertyByName("Object2"));
auto propObject1 = dynamic_cast<App::PropertyXLinkSub*>(joint->getPropertyByName("Object1"));
auto propObject2 = dynamic_cast<App::PropertyXLinkSub*>(joint->getPropertyByName("Object2"));
if (propObject1 && propObject2) {
auto temp = std::string(propObject1->getValue());
auto temp = propObject1->getValue();
auto subs1 = propObject1->getSubValues();
auto subs2 = propObject2->getSubValues();
propObject1->setValue(propObject2->getValue());
propObject1->setSubValues(std::move(subs2));
propObject2->setValue(temp);
propObject2->setSubValues(std::move(subs1));
}
auto propPart1 = dynamic_cast<App::PropertyLink*>(joint->getPropertyByName("Part1"));
auto propPart2 = dynamic_cast<App::PropertyLink*>(joint->getPropertyByName("Part2"));
@@ -1771,12 +1761,12 @@ double AssemblyObject::getEdgeRadius(App::DocumentObject* obj, const char* elt)
DistanceType AssemblyObject::getDistanceType(App::DocumentObject* joint)
{
std::string type1 = getElementTypeFromProp(joint, "Element1");
std::string type2 = getElementTypeFromProp(joint, "Element2");
std::string elt1 = getElementFromProp(joint, "Element1");
std::string elt2 = getElementFromProp(joint, "Element2");
auto* obj1 = getLinkedObjFromNameProp(joint, "Object1", "Part1");
auto* obj2 = getLinkedObjFromNameProp(joint, "Object2", "Part2");
std::string type1 = getElementTypeFromProp(joint, "Object1");
std::string type2 = getElementTypeFromProp(joint, "Object2");
std::string elt1 = getElementFromProp(joint, "Object1");
std::string elt2 = getElementFromProp(joint, "Object2");
auto* obj1 = getLinkedObjFromProp(joint, "Object1");
auto* obj2 = getLinkedObjFromProp(joint, "Object2");
if (type1 == "Vertex" && type2 == "Vertex") {
return DistanceType::PointPoint;
@@ -2118,8 +2108,8 @@ Base::Placement AssemblyObject::getGlobalPlacement(App::DocumentObject* joint,
const char* targetObj,
const char* container)
{
App::DocumentObject* obj = getObjFromNameProp(joint, targetObj, container);
App::DocumentObject* part = getLinkObjFromProp(joint, container);
App::DocumentObject* obj = getObjFromProp(joint, targetObj);
App::DocumentObject* part = getObjFromProp(joint, container);
return getGlobalPlacement(obj, part);
}
@@ -2161,12 +2151,17 @@ JointType AssemblyObject::getJointType(App::DocumentObject* joint)
const char* AssemblyObject::getElementFromProp(App::DocumentObject* obj, const char* propName)
{
auto* prop = dynamic_cast<App::PropertyString*>(obj->getPropertyByName(propName));
auto* prop = dynamic_cast<App::PropertyXLinkSub*>(obj->getPropertyByName(propName));
if (!prop) {
return "";
}
return prop->getValue();
auto subs = prop->getSubValues();
if (subs.empty()) {
return "";
}
return subs[0].c_str();
}
std::string AssemblyObject::getElementTypeFromProp(App::DocumentObject* obj, const char* propName)
@@ -2181,58 +2176,19 @@ std::string AssemblyObject::getElementTypeFromProp(App::DocumentObject* obj, con
return elementType;
}
App::DocumentObject* AssemblyObject::getLinkObjFromProp(App::DocumentObject* joint,
const char* propLinkName)
App::DocumentObject* AssemblyObject::getObjFromProp(App::DocumentObject* joint, const char* pName)
{
auto* propObj = dynamic_cast<App::PropertyLink*>(joint->getPropertyByName(propLinkName));
auto* propObj = dynamic_cast<App::PropertyLink*>(joint->getPropertyByName(pName));
if (!propObj) {
return nullptr;
}
return propObj->getValue();
}
App::DocumentObject* AssemblyObject::getObjFromNameProp(App::DocumentObject* joint,
const char* pObjName,
const char* pPart)
App::DocumentObject* AssemblyObject::getLinkedObjFromProp(App::DocumentObject* joint,
const char* pObj)
{
auto* propObjName = dynamic_cast<App::PropertyString*>(joint->getPropertyByName(pObjName));
if (!propObjName) {
return nullptr;
}
std::string objName = std::string(propObjName->getValue());
App::DocumentObject* containingPart = getLinkObjFromProp(joint, pPart);
if (!containingPart) {
return nullptr;
}
if (objName == containingPart->getNameInDocument()) {
return containingPart;
}
/*if (containingPart->getTypeId().isDerivedFrom(App::Link::getClassTypeId())) {
App::Link* link = dynamic_cast<App::Link*>(containingPart);
containingPart = link->getLinkedObject();
if (!containingPart) {
return nullptr;
}
}*/
for (auto obj : containingPart->getOutListRecursive()) {
if (objName == obj->getNameInDocument()) {
return obj;
}
}
return nullptr;
}
App::DocumentObject* AssemblyObject::getLinkedObjFromNameProp(App::DocumentObject* joint,
const char* pObjName,
const char* pPart)
{
auto* obj = getObjFromNameProp(joint, pObjName, pPart);
auto* obj = getObjFromProp(joint, pObj);
if (obj) {
return obj->getLinkedObject(true);
}

View File

@@ -252,12 +252,8 @@ public:
static JointType getJointType(App::DocumentObject* joint);
static const char* getElementFromProp(App::DocumentObject* obj, const char* propName);
static std::string getElementTypeFromProp(App::DocumentObject* obj, const char* propName);
static App::DocumentObject* getLinkObjFromProp(App::DocumentObject* joint,
const char* propName);
static App::DocumentObject*
getObjFromNameProp(App::DocumentObject* joint, const char* pObjName, const char* pPart);
static App::DocumentObject*
getLinkedObjFromNameProp(App::DocumentObject* joint, const char* pObjName, const char* pPart);
static App::DocumentObject* getObjFromProp(App::DocumentObject* joint, const char* propName);
static App::DocumentObject* getLinkedObjFromProp(App::DocumentObject* joint, const char* pObj);
static Base::Placement getPlacementFromProp(App::DocumentObject* obj, const char* propName);
static bool getTargetPlacementRelativeTo(Base::Placement& foundPlc,
App::DocumentObject* targetObj,

View File

@@ -149,29 +149,29 @@ class TestCore(unittest.TestCase):
box.Placement = App.Placement(App.Vector(10, 20, 30), App.Rotation(15, 25, 35))
# Step 0 : box with placement. No element selected
plc = joint.Proxy.findPlacement(joint, box.Name, box, "", "")
plc = joint.Proxy.findPlacement(joint, box, box, "", "")
targetPlc = App.Placement(App.Vector(), App.Rotation())
self.assertTrue(plc.isSame(targetPlc, 1e-6), "'{}' failed - Step 0".format(operation))
# Step 1 : box with placement. Face + Vertex
plc = joint.Proxy.findPlacement(joint, box.Name, box, "Face6", "Vertex7")
plc = joint.Proxy.findPlacement(joint, box, box, "Face6", "Vertex7")
targetPlc = App.Placement(App.Vector(L, W, H), App.Rotation())
self.assertTrue(plc.isSame(targetPlc, 1e-6), "'{}' failed - Step 1".format(operation))
# Step 2 : box with placement. Edge + Vertex
plc = joint.Proxy.findPlacement(joint, box.Name, box, "Edge8", "Vertex8")
plc = joint.Proxy.findPlacement(joint, box, box, "Edge8", "Vertex8")
targetPlc = App.Placement(App.Vector(L, W, 0), App.Rotation(0, -90, 270))
self.assertTrue(plc.isSame(targetPlc, 1e-6), "'{}' failed - Step 2".format(operation))
# Step 3 : box with placement. Vertex
plc = joint.Proxy.findPlacement(joint, box.Name, box, "Vertex3", "Vertex3")
plc = joint.Proxy.findPlacement(joint, box, box, "Vertex3", "Vertex3")
targetPlc = App.Placement(App.Vector(0, W, H), App.Rotation())
_msg(" plc '{}'".format(plc))
_msg(" targetPlc '{}'".format(targetPlc))
self.assertTrue(plc.isSame(targetPlc, 1e-6), "'{}' failed - Step 3".format(operation))
# Step 4 : box with placement. Face
plc = joint.Proxy.findPlacement(joint, box.Name, box, "Face2", "Face2")
plc = joint.Proxy.findPlacement(joint, box, box, "Face2", "Face2")
targetPlc = App.Placement(App.Vector(L, W / 2, H / 2), App.Rotation(0, -90, 180))
_msg(" plc '{}'".format(plc))
_msg(" targetPlc '{}'".format(targetPlc))

View File

@@ -150,11 +150,11 @@ bool ViewProviderAssembly::canDragObject(App::DocumentObject* obj) const
Gui::Command::openCommand(tr("Delete associated joints").toStdString().c_str());
for (auto joint : allJoints) {
// getLinkObjFromProp returns nullptr if the property doesn't exist.
App::DocumentObject* obj1 = AssemblyObject::getObjFromNameProp(joint, "Object1", "Part1");
App::DocumentObject* obj2 = AssemblyObject::getObjFromNameProp(joint, "Object2", "Part2");
App::DocumentObject* part1 = AssemblyObject::getLinkObjFromProp(joint, "Part1");
App::DocumentObject* part2 = AssemblyObject::getLinkObjFromProp(joint, "Part2");
App::DocumentObject* obj3 = AssemblyObject::getLinkObjFromProp(joint, "ObjectToGround");
App::DocumentObject* obj1 = AssemblyObject::getObjFromProp(joint, "Object1");
App::DocumentObject* obj2 = AssemblyObject::getObjFromProp(joint, "Object2");
App::DocumentObject* part1 = AssemblyObject::getObjFromProp(joint, "Part1");
App::DocumentObject* part2 = AssemblyObject::getObjFromProp(joint, "Part2");
App::DocumentObject* obj3 = AssemblyObject::getObjFromProp(joint, "ObjectToGround");
if (obj == obj1 || obj == obj2 || obj == part1 || obj == part2 || obj == obj3) {
if (!prompted) {
prompted = true;

View File

@@ -172,9 +172,7 @@ def get_active_view(gui_doc):
# The joint object consists of 2 JCS (joint coordinate systems) and a Joint Type.
# A JCS is a placement that is computed (unless it is detached) from :
# - An Object name: this is the name of the solid. It can be any Part::Feature solid.
# Or a PartDesign Body. Or a App::Link to those. We use the name and not directly the DocumentObject
# because the object can be external.
# - An Object: this can be any Part::Feature solid. Or a PartDesign Body. Or a App::Link to those.
# - A Part DocumentObject : This is the lowest level containing part. It can be either the Object itself if it
# stands alone. Or a App::Part. Or a App::Link to a App::Part.
# For example :
@@ -204,10 +202,12 @@ class Joint:
self.createProperties(joint)
def createProperties(self, joint):
self.migrationScript(joint)
# First Joint Connector
if not hasattr(joint, "Object1"):
joint.addProperty(
"App::PropertyString", # Not PropertyLink because they don't support external objects
"App::PropertyXLinkSub",
"Object1",
"Joint Connector 1",
QT_TRANSLATE_NOOP("App::Property", "The first object of the joint"),
@@ -221,22 +221,6 @@ class Joint:
QT_TRANSLATE_NOOP("App::Property", "The first part of the joint"),
)
if not hasattr(joint, "Element1"):
joint.addProperty(
"App::PropertyString",
"Element1",
"Joint Connector 1",
QT_TRANSLATE_NOOP("App::Property", "The selected element of the first object"),
)
if not hasattr(joint, "Vertex1"):
joint.addProperty(
"App::PropertyString",
"Vertex1",
"Joint Connector 1",
QT_TRANSLATE_NOOP("App::Property", "The selected vertex of the first object"),
)
if not hasattr(joint, "Placement1"):
joint.addProperty(
"App::PropertyPlacement",
@@ -262,7 +246,7 @@ class Joint:
# Second Joint Connector
if not hasattr(joint, "Object2"):
joint.addProperty(
"App::PropertyString",
"App::PropertyXLinkSub",
"Object2",
"Joint Connector 2",
QT_TRANSLATE_NOOP("App::Property", "The second object of the joint"),
@@ -276,22 +260,6 @@ class Joint:
QT_TRANSLATE_NOOP("App::Property", "The second part of the joint"),
)
if not hasattr(joint, "Element2"):
joint.addProperty(
"App::PropertyString",
"Element2",
"Joint Connector 2",
QT_TRANSLATE_NOOP("App::Property", "The selected element of the second object"),
)
if not hasattr(joint, "Vertex2"):
joint.addProperty(
"App::PropertyString",
"Vertex2",
"Joint Connector 2",
QT_TRANSLATE_NOOP("App::Property", "The selected vertex of the second object"),
)
if not hasattr(joint, "Placement2"):
joint.addProperty(
"App::PropertyPlacement",
@@ -314,6 +282,7 @@ class Joint:
),
)
# Other properties
if not hasattr(joint, "Distance"):
joint.addProperty(
"App::PropertyFloat",
@@ -462,6 +431,45 @@ class Joint:
),
)
def migrationScript(self, joint):
if hasattr(joint, "Object1") and isinstance(joint.Object1, str):
objName = joint.Object1
obj1 = UtilsAssembly.getObjectInPart(objName, joint.Part1)
el1 = joint.Element1
vtx1 = joint.Vertex1
joint.removeProperty("Object1")
joint.removeProperty("Element1")
joint.removeProperty("Vertex1")
joint.addProperty(
"App::PropertyXLinkSub",
"Object1",
"Joint Connector 1",
QT_TRANSLATE_NOOP("App::Property", "The first object of the joint"),
)
joint.Object1 = [obj1, [el1, vtx1]]
if hasattr(joint, "Object2") and isinstance(joint.Object2, str):
objName = joint.Object2
obj2 = UtilsAssembly.getObjectInPart(objName, joint.Part2)
el2 = joint.Element2
vtx2 = joint.Vertex2
joint.removeProperty("Object2")
joint.removeProperty("Element2")
joint.removeProperty("Vertex2")
joint.addProperty(
"App::PropertyXLinkSub",
"Object2",
"Joint Connector 2",
QT_TRANSLATE_NOOP("App::Property", "The second object of the joint"),
)
joint.Object2 = [obj2, [el2, vtx2]]
def dumps(self):
return None
@@ -482,30 +490,28 @@ class Joint:
"""Do something when a property has changed"""
# App.Console.PrintMessage("Change property: " + str(prop) + "\n")
# during loading the onchanged may be triggered before full init.
if App.isRestoring():
return
if prop == "Rotation" or prop == "Offset":
# during loading the onchanged may be triggered before full init.
if hasattr(joint, "Vertex1"): # so we check Vertex1
self.updateJCSPlacements(joint)
if joint.Object1 is None or joint.Object2 is None:
return
presolved = self.preSolve(joint, False)
isAssembly = self.getAssembly(joint).Type == "Assembly"
if isAssembly and not presolved:
solveIfAllowed(self.getAssembly(joint))
else:
self.updateJCSPlacements(joint)
obj1 = UtilsAssembly.getObjectInPart(joint.Object1, joint.Part1)
obj2 = UtilsAssembly.getObjectInPart(joint.Object2, joint.Part2)
if obj1 is None or obj2 is None:
return
presolved = self.preSolve(joint, False)
isAssembly = self.getAssembly(joint).Type == "Assembly"
if isAssembly and not presolved:
solveIfAllowed(self.getAssembly(joint))
else:
self.updateJCSPlacements(joint)
if prop == "Distance" and (joint.JointType == "Distance" or joint.JointType == "Angle"):
# during loading the onchanged may be triggered before full init.
if hasattr(joint, "Vertex1"): # so we check Vertex1
if joint.Part1 and joint.Part2:
if joint.JointType == "Angle" and joint.Distance != 0.0:
self.preventParallel(joint)
solveIfAllowed(self.getAssembly(joint))
if joint.Part1 and joint.Part2:
if joint.JointType == "Angle" and joint.Distance != 0.0:
self.preventParallel(joint)
solveIfAllowed(self.getAssembly(joint))
def execute(self, fp):
"""Do something when doing a recomputation, this method is mandatory"""
@@ -518,28 +524,28 @@ class Joint:
isAssembly = assembly.Type == "Assembly"
if len(current_selection) >= 1:
joint.Object1 = current_selection[0]["object"].Name
joint.Object1 = [
current_selection[0]["object"],
[current_selection[0]["element_name"], current_selection[0]["vertex_name"]],
]
joint.Part1 = current_selection[0]["part"]
joint.Element1 = current_selection[0]["element_name"]
joint.Vertex1 = current_selection[0]["vertex_name"]
joint.Placement1 = self.findPlacement(
joint, joint.Object1, joint.Part1, joint.Element1, joint.Vertex1
joint, joint.Object1[0], joint.Part1, joint.Object1[1][0], joint.Object1[1][1]
)
else:
joint.Object1 = ""
joint.Object1 = None
joint.Part1 = None
joint.Element1 = ""
joint.Vertex1 = ""
joint.Placement1 = App.Placement()
self.partMovedByPresolved = None
if len(current_selection) >= 2:
joint.Object2 = current_selection[1]["object"].Name
joint.Object2 = [
current_selection[1]["object"],
[current_selection[1]["element_name"], current_selection[1]["vertex_name"]],
]
joint.Part2 = current_selection[1]["part"]
joint.Element2 = current_selection[1]["element_name"]
joint.Vertex2 = current_selection[1]["vertex_name"]
joint.Placement2 = self.findPlacement(
joint, joint.Object2, joint.Part2, joint.Element2, joint.Vertex2, True
joint, joint.Object2[0], joint.Part2, joint.Object2[1][0], joint.Object2[1][1], True
)
if joint.JointType in JointUsingPreSolve:
self.preSolve(joint)
@@ -552,10 +558,8 @@ class Joint:
self.updateJCSPlacements(joint)
else:
joint.Object2 = ""
joint.Object2 = None
joint.Part2 = None
joint.Element2 = ""
joint.Vertex2 = ""
joint.Placement2 = App.Placement()
if isAssembly:
assembly.undoSolve()
@@ -564,12 +568,12 @@ class Joint:
def updateJCSPlacements(self, joint):
if not joint.Detach1:
joint.Placement1 = self.findPlacement(
joint, joint.Object1, joint.Part1, joint.Element1, joint.Vertex1
joint, joint.Object1[0], joint.Part1, joint.Object1[1][0], joint.Object1[1][1]
)
if not joint.Detach2:
joint.Placement2 = self.findPlacement(
joint, joint.Object2, joint.Part2, joint.Element2, joint.Vertex2, True
joint, joint.Object2[0], joint.Part2, joint.Object2[1][0], joint.Object2[1][1], True
)
"""
@@ -582,12 +586,10 @@ class Joint:
- if elt is a cylindrical face, vtx can also be the center of the arcs of the cylindrical face.
"""
def findPlacement(self, joint, objName, part, elt, vtx, isSecond=False):
if not objName or not part:
def findPlacement(self, joint, obj, part, elt, vtx, isSecond=False):
if not obj or not part:
return App.Placement()
obj = UtilsAssembly.getObjectInPart(objName, part)
ignoreVertex = joint.JointType == "Distance"
plc = UtilsAssembly.findPlacement(obj, part, elt, vtx, ignoreVertex)
@@ -607,20 +609,20 @@ class Joint:
part2Grounded = assembly.isPartGrounded(joint.Part2)
if part2ConnectedByJoint and not part2Grounded:
jcsPlc = UtilsAssembly.getJcsPlcRelativeToPart(
joint.Placement2, joint.Object2, joint.Part2
joint.Placement2, joint.Object2[0], joint.Part2
)
globalJcsPlc = UtilsAssembly.getJcsGlobalPlc(
joint.Placement2, joint.Object2, joint.Part2
joint.Placement2, joint.Object2[0], joint.Part2
)
jcsPlc = UtilsAssembly.flipPlacement(jcsPlc)
joint.Part2.Placement = globalJcsPlc * jcsPlc.inverse()
elif not part1Grounded:
jcsPlc = UtilsAssembly.getJcsPlcRelativeToPart(
joint.Placement1, joint.Object1, joint.Part1
joint.Placement1, joint.Object1[0], joint.Part1
)
globalJcsPlc = UtilsAssembly.getJcsGlobalPlc(
joint.Placement1, joint.Object1, joint.Part1
joint.Placement1, joint.Object1[0], joint.Part1
)
jcsPlc = UtilsAssembly.flipPlacement(jcsPlc)
joint.Part1.Placement = globalJcsPlc * jcsPlc.inverse()
@@ -650,10 +652,10 @@ class Joint:
self.presolveBackupPlc = joint.Part2.Placement
globalJcsPlc1 = UtilsAssembly.getJcsGlobalPlc(
joint.Placement1, joint.Object1, joint.Part1
joint.Placement1, joint.Object1[0], joint.Part1
)
jcsPlc2 = UtilsAssembly.getJcsPlcRelativeToPart(
joint.Placement2, joint.Object2, joint.Part2
joint.Placement2, joint.Object2[0], joint.Part2
)
if not sameDir:
jcsPlc2 = UtilsAssembly.flipPlacement(jcsPlc2)
@@ -666,10 +668,10 @@ class Joint:
self.presolveBackupPlc = joint.Part1.Placement
globalJcsPlc2 = UtilsAssembly.getJcsGlobalPlc(
joint.Placement2, joint.Object2, joint.Part2
joint.Placement2, joint.Object2[0], joint.Part2
)
jcsPlc1 = UtilsAssembly.getJcsPlcRelativeToPart(
joint.Placement1, joint.Object1, joint.Part1
joint.Placement1, joint.Object1[0], joint.Part1
)
if not sameDir:
jcsPlc1 = UtilsAssembly.flipPlacement(jcsPlc1)
@@ -716,14 +718,22 @@ class Joint:
)
def areJcsSameDir(self, joint):
globalJcsPlc1 = UtilsAssembly.getJcsGlobalPlc(joint.Placement1, joint.Object1, joint.Part1)
globalJcsPlc2 = UtilsAssembly.getJcsGlobalPlc(joint.Placement2, joint.Object2, joint.Part2)
globalJcsPlc1 = UtilsAssembly.getJcsGlobalPlc(
joint.Placement1, joint.Object1[0], joint.Part1
)
globalJcsPlc2 = UtilsAssembly.getJcsGlobalPlc(
joint.Placement2, joint.Object2[0], joint.Part2
)
return UtilsAssembly.arePlacementSameDir(globalJcsPlc1, globalJcsPlc2)
def areJcsZParallel(self, joint):
globalJcsPlc1 = UtilsAssembly.getJcsGlobalPlc(joint.Placement1, joint.Object1, joint.Part1)
globalJcsPlc2 = UtilsAssembly.getJcsGlobalPlc(joint.Placement2, joint.Object2, joint.Part2)
globalJcsPlc1 = UtilsAssembly.getJcsGlobalPlc(
joint.Placement1, joint.Object1[0], joint.Part1
)
globalJcsPlc2 = UtilsAssembly.getJcsGlobalPlc(
joint.Placement2, joint.Object2[0], joint.Part2
)
return UtilsAssembly.arePlacementZParallel(globalJcsPlc1, globalJcsPlc2)
@@ -862,9 +872,8 @@ class ViewProviderJoint:
def get_JCS_size(self):
return get_camera_height(self.gui_doc) / 20
def set_JCS_placement(self, soTransform, placement, objName, part):
def set_JCS_placement(self, soTransform, placement, obj, part):
# change plc to be relative to the origin of the document.
obj = UtilsAssembly.getObjectInPart(objName, part)
global_plc = UtilsAssembly.getGlobalPlacement(obj, part)
placement = global_plc * placement
@@ -883,7 +892,7 @@ class ViewProviderJoint:
self.switch_JCS1.whichChild = coin.SO_SWITCH_ALL
if joint.Part1:
self.set_JCS_placement(self.transform1, plc, joint.Object1, joint.Part1)
self.set_JCS_placement(self.transform1, plc, joint.Object1[0], joint.Part1)
else:
self.switch_JCS1.whichChild = coin.SO_SWITCH_NONE
@@ -893,14 +902,14 @@ class ViewProviderJoint:
self.switch_JCS2.whichChild = coin.SO_SWITCH_ALL
if joint.Part2:
self.set_JCS_placement(self.transform2, plc, joint.Object2, joint.Part2)
self.set_JCS_placement(self.transform2, plc, joint.Object2[0], joint.Part2)
else:
self.switch_JCS2.whichChild = coin.SO_SWITCH_NONE
def showPreviewJCS(self, visible, placement=None, objName="", part=None):
def showPreviewJCS(self, visible, placement=None, obj=None, part=None):
if visible:
self.switch_JCS_preview.whichChild = coin.SO_SWITCH_ALL
self.set_JCS_placement(self.transform3, placement, objName, part)
self.set_JCS_placement(self.transform3, placement, obj, part)
else:
self.switch_JCS_preview.whichChild = coin.SO_SWITCH_NONE
@@ -1626,21 +1635,28 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
self.current_selection = []
self.preselection_dict = None
obj1 = UtilsAssembly.getObjectInPart(self.joint.Object1, self.joint.Part1)
obj2 = UtilsAssembly.getObjectInPart(self.joint.Object2, self.joint.Part2)
obj1 = self.joint.Object1[0]
part1 = self.joint.Part1
el1 = self.joint.Object1[1][0]
vtx1 = self.joint.Object1[1][1]
obj2 = self.joint.Object2[0]
part2 = self.joint.Part2
el2 = self.joint.Object2[1][0]
vtx2 = self.joint.Object2[1][1]
selection_dict1 = {
"object": obj1,
"part": self.joint.Part1,
"element_name": self.joint.Element1,
"vertex_name": self.joint.Vertex1,
"part": part1,
"element_name": el1,
"vertex_name": vtx1,
}
selection_dict2 = {
"object": obj2,
"part": self.joint.Part2,
"element_name": self.joint.Element2,
"vertex_name": self.joint.Vertex2,
"part": part2,
"element_name": el2,
"vertex_name": vtx2,
}
self.current_selection.append(selection_dict1)
@@ -1651,11 +1667,11 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
# Because obj1 can be external in which case addSelection will fail. And
# Gui.Selection.addSelection(obj1.Document.Name, obj1.Name, elName)
# will not select in the assembly doc.
elName = self.getSubnameForSelection(obj1, self.joint.Part1, self.joint.Element1)
Gui.Selection.addSelection(self.doc.Name, self.joint.Part1.Name, elName)
elName = self.getSubnameForSelection(obj1, part1, el1)
Gui.Selection.addSelection(self.doc.Name, part1.Name, elName)
elName = self.getSubnameForSelection(obj2, self.joint.Part2, self.joint.Element2)
Gui.Selection.addSelection(self.doc.Name, self.joint.Part2.Name, elName)
elName = self.getSubnameForSelection(obj2, part2, el2)
Gui.Selection.addSelection(self.doc.Name, part2.Name, elName)
self.form.distanceSpinbox.setProperty("rawValue", self.joint.Distance)
self.form.distanceSpinbox2.setProperty("rawValue", self.joint.Distance2)
@@ -1791,17 +1807,17 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
)
isSecond = len(self.current_selection) == 1
objName = self.preselection_dict["object"].Name
obj = self.preselection_dict["object"]
part = self.preselection_dict["part"]
placement = self.joint.Proxy.findPlacement(
self.joint,
objName,
obj,
part,
self.preselection_dict["element_name"],
self.preselection_dict["vertex_name"],
isSecond,
)
self.joint.ViewObject.Proxy.showPreviewJCS(True, placement, objName, part)
self.joint.ViewObject.Proxy.showPreviewJCS(True, placement, obj, part)
self.previewJCSVisible = True
# 3D view keyboard handler

View File

@@ -268,9 +268,7 @@ def getObjectInPart(objName, part):
# get the placement of Obj relative to its containing Part
# Example : assembly.part1.part2.partn.body1 : placement of Obj relative to part1
def getObjPlcRelativeToPart(objName, part):
obj = getObjectInPart(objName, part)
def getObjPlcRelativeToPart(obj, part):
# we need plc to be relative to the containing part
obj_global_plc = getGlobalPlacement(obj, part)
part_global_plc = getGlobalPlacement(part)
@@ -280,15 +278,13 @@ def getObjPlcRelativeToPart(objName, part):
# Example : assembly.part1.part2.partn.body1 : jcsPlc is relative to body1
# This function returns jcsPlc relative to part1
def getJcsPlcRelativeToPart(jcsPlc, objName, part):
obj_relative_plc = getObjPlcRelativeToPart(objName, part)
def getJcsPlcRelativeToPart(jcsPlc, obj, part):
obj_relative_plc = getObjPlcRelativeToPart(obj, part)
return obj_relative_plc * jcsPlc
# Return the jcs global placement
def getJcsGlobalPlc(jcsPlc, objName, part):
obj = getObjectInPart(objName, part)
def getJcsGlobalPlc(jcsPlc, obj, part):
obj_global_plc = getGlobalPlacement(obj, part)
return obj_global_plc * jcsPlc