Fix Assembly solver ignoring PartDesign datum plane references

When a PartDesign::Plane (including ZTools datums like ZPlane_Mid,
ZPlane_Offset) is used as a reference in an Assembly joint,
findPlacement() returns an all-zero placement, making the joint
constraint degenerate and ineffective.

Root cause: getElementName() strips the terminal '.Plane' suffix
because it matches the hardcoded set for App::LocalCoordinateSystem
datum elements ({X, Y, Z, Point, Line, Plane}). This is correct
behavior — the issue is that findPlacement()'s 'whole part' branch
only handled App::Line objects and returned App.Placement() (zeros)
for everything else, including PartDesign::Plane datums.

The fix extends the 'whole part' branch in findPlacement() to
compute a proper placement for PartDesign::Plane objects by
extracting the plane's center-of-gravity and surface rotation from
its Shape, then converting to object-local coordinates. This matches
the existing convention used for Face elements elsewhere in the
function.

Also adds handling for PartDesign::Point datums, which hit the same
empty-element code path.

Existing App::Plane origin references (XY_Plane, etc.) are unaffected
since isDerivedFrom('PartDesign::Plane') does not match App::Plane.
This commit is contained in:
forbes
2026-01-30 20:46:32 -06:00
parent a9c444131a
commit ddefb23652

View File

@@ -1004,6 +1004,22 @@ def findPlacement(ref, ignoreVertex=False):
return App.Placement(App.Vector(), App.Rotation(0.5, 0.5, 0.5, 0.5))
if obj.Role == "Z_Axis":
return App.Placement(App.Vector(), App.Rotation(-0.5, 0.5, -0.5, 0.5))
# PartDesign datum planes (including ZTools datums like ZPlane_Mid, ZPlane_Offset)
if obj.isDerivedFrom("PartDesign::Plane"):
if hasattr(obj, "Shape") and obj.Shape.Faces:
face = obj.Shape.Faces[0]
surface = face.Surface
plc = App.Placement()
plc.Base = face.CenterOfGravity
if hasattr(surface, "Rotation") and surface.Rotation is not None:
plc.Rotation = App.Rotation(surface.Rotation)
return obj.Placement.inverse() * plc
# PartDesign datum points
if obj.isDerivedFrom("PartDesign::Point"):
return obj.Placement
return App.Placement()
plc = App.Placement()