Draft: fix NaN issue with Draft_Rotate

Fixes #19690

The issue was caused by a zero distance between the center and the point picked for the rotation angle.
This commit is contained in:
Roy-043
2025-03-01 20:11:15 +01:00
committed by Yorik van Havre
parent 084a0b3b4a
commit ff9e84e181

View File

@@ -36,6 +36,7 @@ from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD as App
import FreeCADGui as Gui
import DraftVecUtils
from draftgeoutils import geometry
from draftguitools import gui_base_original
from draftguitools import gui_tool_utils
from draftguitools import gui_trackers as trackers
@@ -81,6 +82,8 @@ class Rotate(gui_base_original.Modifier):
Gui.doCommand("selection = FreeCADGui.Selection.getSelectionEx(\"\", 0)")
self.step = 0
self.center = None
self.point = None
self.firstangle = None
self.ui.rotateSetCenterUi()
self.arctrack = trackers.arcTracker()
self.call = self.view.addEventCallback("SoEvent", self.action)
@@ -106,17 +109,35 @@ class Rotate(gui_base_original.Modifier):
and arg["Button"] == "BUTTON1"):
self.handle_mouse_click_event(arg)
def _get_angle(self):
if self.center is None:
return 0
if self.point is None:
return 0
if DraftVecUtils.dist(self.point, self.center) < 1e-7:
return 0
angle = DraftVecUtils.angle(self.wp.u, self.point.sub(self.center), self.wp.axis)
if self.firstangle is None:
return angle
if angle < self.firstangle:
return (2 * math.pi - self.firstangle) + angle
return angle - self.firstangle
def handle_mouse_move_event(self, arg):
"""Handle the mouse when moving."""
for ghost in self.ghosts:
ghost.off()
self.point, ctrlPoint, info = gui_tool_utils.getPoint(self, arg)
# this is to make sure radius is what you see on screen
if self.center and self.point and DraftVecUtils.dist(self.point, self.center):
viewdelta = DraftVecUtils.project(self.point.sub(self.center),
self.wp.axis)
if not DraftVecUtils.isNull(viewdelta):
self.point = self.point.add(viewdelta.negative())
if self.center is not None:
# Project self.point on a plane that is parallel to the wp and that
# passes through self.center.
self.point = geometry.project_point_on_plane(
self.point,
self.center,
self.wp.axis,
direction=None,
force_projection=True
)
if self.extendedCopy:
if not gui_tool_utils.hasMod(arg, gui_tool_utils.get_mod_alt_key()):
self.step = 3
@@ -124,35 +145,17 @@ class Rotate(gui_base_original.Modifier):
if self.step == 0:
pass
elif self.step == 1:
angle = 0
if self.point:
currentrad = DraftVecUtils.dist(self.point, self.center)
if currentrad != 0:
angle = DraftVecUtils.angle(self.wp.u,
self.point.sub(self.center),
self.wp.axis)
angle = self._get_angle()
self.ui.setRadiusValue(math.degrees(angle), unit="Angle")
self.firstangle = angle
self.ui.radiusValue.setFocus()
self.ui.radiusValue.selectAll()
elif self.step == 2:
angle = 0
if self.point:
currentrad = DraftVecUtils.dist(self.point, self.center)
if currentrad != 0:
angle = DraftVecUtils.angle(self.wp.u,
self.point.sub(self.center),
self.wp.axis)
if angle < self.firstangle:
sweep = (2 * math.pi - self.firstangle) + angle
else:
sweep = angle - self.firstangle
self.arctrack.setApertureAngle(sweep)
angle = self._get_angle()
self.arctrack.setApertureAngle(angle)
for ghost in self.ghosts:
if sweep:
ghost.rotate(self.wp.axis, sweep)
ghost.rotate(self.wp.axis, angle)
ghost.on()
self.ui.setRadiusValue(math.degrees(sweep), 'Angle')
self.ui.setRadiusValue(math.degrees(angle), unit="Angle")
self.ui.radiusValue.setFocus()
self.ui.radiusValue.selectAll()
gui_tool_utils.redraw3DView()
@@ -189,9 +192,9 @@ class Rotate(gui_base_original.Modifier):
def set_start_point(self):
"""Set the starting point of the rotation."""
self.firstangle = self._get_angle()
self.ui.labelRadius.setText(translate("draft", "Rotation"))
self.ui.radiusValue.setToolTip(translate("draft", "The amount of rotation you wish to perform.\nThe final angle will be the base angle plus this amount."))
self.rad = DraftVecUtils.dist(self.point, self.center)
self.arctrack.on()
self.arctrack.setStartPoint(self.point)
for ghost in self.ghosts:
@@ -201,18 +204,10 @@ class Rotate(gui_base_original.Modifier):
def set_rotation_angle(self, arg):
"""Set the rotation angle."""
# currentrad = DraftVecUtils.dist(self.point, self.center)
angle = self.point.sub(self.center).getAngle(self.wp.u)
_v = DraftVecUtils.project(self.point.sub(self.center), self.wp.v)
if _v.getAngle(self.wp.v) > 1:
angle = -angle
if angle < self.firstangle:
self.angle = (2 * math.pi - self.firstangle) + angle
else:
self.angle = angle - self.firstangle
self.rotate(self.ui.isCopy.isChecked()
or gui_tool_utils.hasMod(arg, gui_tool_utils.get_mod_alt_key()))
self.angle = self._get_angle()
if self.angle != 0:
self.rotate(self.ui.isCopy.isChecked()
or gui_tool_utils.hasMod(arg, gui_tool_utils.get_mod_alt_key()))
if gui_tool_utils.hasMod(arg, gui_tool_utils.get_mod_alt_key()):
self.extendedCopy = True
else: