Assembly: fix joint creation not working on draft links (#26085)

* Assembly: add support for draft links

* Update AssemblyObject.cpp

* Update ViewProviderAssembly.cpp

* Update GeoFeature.cpp

* Update JointObject.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* [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:
PaddleStroke
2026-03-09 18:15:01 +01:00
committed by GitHub
co-authored by pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
parent 79923c16f3
commit e20b42e484
5 changed files with 21 additions and 30 deletions
+2 -1
View File
@@ -328,7 +328,7 @@ Base::Placement GeoFeature::getGlobalPlacement(App::DocumentObject* targetObj,
Base::Placement GeoFeature::getGlobalPlacement(App::DocumentObject* targetObj,
App::PropertyXLinkSub* prop)
{
if (!targetObj || !prop) {
if (!prop) {
return Base::Placement();
}
@@ -357,3 +357,4 @@ Base::Placement GeoFeature::getGlobalPlacement(const DocumentObject* obj)
return placementProperty->getValue();
}
+13 -13
View File
@@ -1657,20 +1657,20 @@ std::string AssemblyObject::handleOneSideOfJoint(
Base::Placement plc = getPlacementFromProp(joint, propPlcName);
// Now we have plc which is the JCS placement, but its relative to the Object, not to the
// containing Part.
if (obj->getNameInDocument() != part->getNameInDocument()) {
auto* ref = dynamic_cast<App::PropertyXLinkSub*>(joint->getPropertyByName(propRefName));
if (!ref) {
return "";
}
Base::Placement obj_global_plc = getGlobalPlacement(obj, ref);
plc = obj_global_plc * plc;
Base::Placement part_global_plc = getGlobalPlacement(part, ref);
plc = part_global_plc.inverse() * plc;
auto* ref = dynamic_cast<App::PropertyXLinkSub*>(joint->getPropertyByName(propRefName));
if (!ref) {
return "";
}
// This plc adjustment should be necessary only if obj != part. But for some objects like
// draft links, we can have obj == part and still need to get global placement to adjust
// by the element placement.
Base::Placement obj_global_plc = getGlobalPlacement(nullptr, ref);
plc = obj_global_plc * plc;
// Note part is supposed to be root of ref, so we could use part.Placement directly.
Base::Placement part_global_plc = getGlobalPlacement(part, ref);
plc = part_global_plc.inverse() * plc;
// check if we need to add an offset in case of bundled parts.
if (!data.offsetPlc.isIdentity()) {
plc = data.offsetPlc * plc;
@@ -979,7 +979,7 @@ ViewProviderAssembly::DragMode ViewProviderAssembly::findDragMode()
return DragMode::Translation;
}
auto* obj = getObjFromJointRef(movingJoint, pName.c_str());
Base::Placement global_plc = App::GeoFeature::getGlobalPlacement(obj, ref);
Base::Placement global_plc = App::GeoFeature::getGlobalPlacement(nullptr, ref);
jcsGlobalPlc = global_plc * jcsPlc;
// Add downstream parts so that they move together
+2
View File
@@ -2219,6 +2219,8 @@ class TaskAssemblyCreateJoint(QtCore.QObject):
self.presel_ref = None
return
sub_name = UtilsAssembly.fixBodyExtraFeatureInSub(doc_name, sub_name)
rootObj = App.getDocument(doc_name).getObject(obj_name)
comp, new_sub = UtilsAssembly.getComponentReference(self.assembly, rootObj, sub_name)
+3 -15
View File
@@ -364,11 +364,6 @@ def getGlobalPlacement(ref, targetObj=None):
if not isRefValid(ref, 1):
return App.Placement()
if targetObj is None: # If no targetObj is given, we consider it's the getObject(ref)
targetObj = getObject(ref)
if targetObj is None:
return App.Placement()
rootObj = ref[0]
subName = ref[1][0]
# ref[0] is no longer the root object. Now it's the moving part.
@@ -1098,9 +1093,9 @@ def findPlacement(ref, ignoreVertex=False):
if hasattr(surface, "Rotation") and surface.Rotation is not None:
plc.Rotation = App.Rotation(surface.Rotation)
# Now plc is the placement relative to the origin determined by the object placement.
# But it does not take into account Part placements. So if the solid is in a part and
# if the part has a placement then plc is wrong.
if hasattr(obj, "ExpandArray"):
# For draft arrays, the Shape has both the array placement and the base placement.
plc = obj.Base.Placement.inverse() * plc
# change plc to be relative to the object placement.
plc = obj.Placement.inverse() * plc
@@ -1114,13 +1109,6 @@ def findPlacement(ref, ignoreVertex=False):
plane = Part.Plane(plane_origin, plane_normal)
plc.Rotation = App.Rotation(plane.Rotation)
# change plc to be relative to the origin of the document.
# global_plc = getGlobalPlacement(obj, part)
# plc = global_plc * plc
# change plc to be relative to the assembly.
# plc = activeAssembly().Placement.inverse() * plc
return plc