Skip to content

Commit 8fd81d4

Browse files
authored
Assembly: Ball drag mode. (FreeCAD#26222)
1 parent a13502d commit 8fd81d4

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

src/Mod/Assembly/Gui/ViewProviderAssembly.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,28 @@ bool ViewProviderAssembly::tryMouseMove(const SbVec2s& cursorPos, Gui::View3DInv
503503
Base::Placement jcsPlcRelativeToPart = plc.inverse() * jcsGlobalPlc;
504504
plc = rotatedGlovalJcsPlc * jcsPlcRelativeToPart.inverse();
505505
}
506+
else if (dragMode == DragMode::Ball) {
507+
Base::Vector3d center = jcsGlobalPlc.getPosition();
508+
// Vectors from joint center to initial click and current drag position
509+
Base::Vector3d u = initialPosition - center;
510+
Base::Vector3d v = newPos - center;
511+
512+
// Ensure vectors are valid to prevent singularities
513+
if (u.Length() > Precision::Confusion() && v.Length() > Precision::Confusion()) {
514+
// Calculate rotation that moves vector u to v
515+
Base::Rotation rot;
516+
rot.setValue(u, v);
517+
518+
// Apply this rotation to the global joint placement (around the joint center)
519+
Base::Placement rotatedGlobalJcsPlc = jcsGlobalPlc;
520+
rotatedGlobalJcsPlc.setRotation(rot * jcsGlobalPlc.getRotation());
521+
522+
// Calculate the initial offset of the part relative to the joint
523+
// and apply the new global joint placement to find the new part placement.
524+
Base::Placement jcsPlcRelativeToPart = plc.inverse() * jcsGlobalPlc;
525+
plc = rotatedGlobalJcsPlc * jcsPlcRelativeToPart.inverse();
526+
}
527+
}
506528
else if (dragMode == DragMode::TranslationOnAxis) {
507529
Base::Vector3d pos = plc.getPosition() + (newPos - initialPosition);
508530
plc.setPosition(pos);
@@ -942,7 +964,7 @@ ViewProviderAssembly::DragMode ViewProviderAssembly::findDragMode()
942964
return DragMode::TranslationOnAxisAndRotationOnePlane;
943965
}
944966
else if (jointType == JointType::Ball) {
945-
// return DragMode::Ball;
967+
return DragMode::Ball;
946968
}
947969
else if (jointType == JointType::Distance) {
948970
// depends on the type of distance. For example plane-plane:

0 commit comments

Comments
 (0)