diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py index bfbf433fa8..c5823e1773 100644 --- a/src/Mod/Path/InitGui.py +++ b/src/Mod/Path/InitGui.py @@ -275,7 +275,10 @@ class PathWorkbench(Workbench): msgbox = QtGui.QMessageBox(QtGui.QMessageBox.Warning, header, msg) msgbox.addButton(translate("Path", "Ok"), QtGui.QMessageBox.AcceptRole) - msgbox.addButton(translate("Path", "Don't Show This Anymore"), QtGui.QMessageBox.ActionRole) + msgbox.addButton( + translate("Path", "Don't Show This Anymore"), + QtGui.QMessageBox.ActionRole, + ) if msgbox.exec_() == 1: preferences().SetBool("WarningSuppressVelocity", True) diff --git a/src/Mod/Path/PathScripts/PathArray.py b/src/Mod/Path/PathScripts/PathArray.py index c834187e8c..2f5858aa9d 100644 --- a/src/Mod/Path/PathScripts/PathArray.py +++ b/src/Mod/Path/PathScripts/PathArray.py @@ -516,7 +516,10 @@ class CommandPathArray: } def IsActive(self): - selections = [sel.isDerivedFrom("Path::Feature") for sel in FreeCADGui.Selection.getSelection()] + selections = [ + sel.isDerivedFrom("Path::Feature") + for sel in FreeCADGui.Selection.getSelection() + ] return selections and all(selections) def Activated(self): diff --git a/src/Mod/Path/PathScripts/PathGui.py b/src/Mod/Path/PathScripts/PathGui.py index c32cdedf56..6bdd15f411 100644 --- a/src/Mod/Path/PathScripts/PathGui.py +++ b/src/Mod/Path/PathScripts/PathGui.py @@ -25,6 +25,7 @@ import PathScripts.PathGeom as PathGeom import PathScripts.PathLog as PathLog import PathScripts.PathUtil as PathUtil +from PySide import QtCore, QtGui __title__ = "Path UI helper and utility functions" __author__ = "sliptonic (Brad Collette)" @@ -66,7 +67,6 @@ def updateInputField(obj, prop, widget, onBeforeChange=None): If onBeforeChange is specified it is called before a new value is assigned to the property. Returns True if a new value was assigned, False otherwise (new value is the same as the current). """ - PathLog.track() value = widget.property("rawValue") PathLog.track("value: {}".format(value)) attr = PathUtil.getProperty(obj, prop) @@ -77,21 +77,21 @@ def updateInputField(obj, prop, widget, onBeforeChange=None): isDiff = True else: if hasattr(obj, "ExpressionEngine"): - noExpr = True + exprSet = False for (prp, expr) in obj.ExpressionEngine: if prp == prop: - noExpr = False + exprSet = True PathLog.debug('prop = "expression": {} = "{}"'.format(prp, expr)) value = FreeCAD.Units.Quantity(obj.evalExpression(expr)).Value if not PathGeom.isRoughly(attrValue, value): isDiff = True break - if noExpr: - widget.setReadOnly(False) - widget.setStyleSheet("color: black") - else: + if exprSet: widget.setReadOnly(True) widget.setStyleSheet("color: gray") + else: + widget.setReadOnly(False) + widget.setStyleSheet("color: black") widget.update() if isDiff: @@ -106,7 +106,7 @@ def updateInputField(obj, prop, widget, onBeforeChange=None): return False -class QuantitySpinBox: +class QuantitySpinBox(QtCore.QObject): """Controller class to interface a Gui::QuantitySpinBox. The spin box gets bound to a given property and supports update in both directions. QuatitySpinBox(widget, obj, prop, onBeforeChange=None) @@ -117,12 +117,19 @@ class QuantitySpinBox: """ def __init__(self, widget, obj, prop, onBeforeChange=None): + super().__init__() PathLog.track(widget) self.widget = widget self.onBeforeChange = onBeforeChange self.prop = None self.obj = obj self.attachTo(obj, prop) + self.widget.installEventFilter(self) + + def eventFilter(self, obj, event): + if event.type() == QtCore.QEvent.Type.FocusIn: + self.updateSpinBox() + return False def attachTo(self, obj, prop=None): """attachTo(obj, prop=None) ... use an existing editor for the given object and property""" @@ -160,7 +167,7 @@ class QuantitySpinBox: """updateSpinBox(quantity=None) ... update the display value of the spin box. If no value is provided the value of the bound property is used. quantity can be of type Quantity or Float.""" - PathLog.track(self.prop, self.valid) + PathLog.track(self.prop, self.valid, quantity) if self.valid: expr = self._hasExpression() @@ -171,6 +178,12 @@ class QuantitySpinBox: quantity = PathUtil.getProperty(self.obj, self.prop) value = quantity.Value if hasattr(quantity, "Value") else quantity self.widget.setProperty("rawValue", value) + if expr: + self.widget.setReadOnly(True) + self.widget.setStyleSheet("color: gray") + else: + self.widget.setReadOnly(False) + self.widget.setStyleSheet("color: black") def updateProperty(self): """updateProperty() ... update the bound property with the value from the spin box""" diff --git a/src/Mod/Path/PathScripts/PathJobGui.py b/src/Mod/Path/PathScripts/PathJobGui.py index 15294360d4..b1ae35eff1 100644 --- a/src/Mod/Path/PathScripts/PathJobGui.py +++ b/src/Mod/Path/PathScripts/PathJobGui.py @@ -1088,12 +1088,25 @@ class TaskPanel: PathLog.track( "Vector(%.2f, %.2f, %.2f)" % (normal.x, normal.y, normal.z), flip ) - vector = axis + v = axis if flip: - vector = axis.negative() - r = axis.cross(normal) # rotation axis - a = DraftVecUtils.angle(normal, vector, r) * 180 / math.pi - PathLog.debug("oh boy: (%.2f, %.2f, %.2f) -> %.2f" % (r.x, r.y, r.z, a)) + v = axis.negative() + + if PathGeom.pointsCoincide(abs(v), abs(normal)): + # Selection is already aligned with the axis of rotation leading + # to a (0,0,0) cross product for rotation. + # --> Need to flip the object around one of the "other" axis. + # Simplest way to achieve that is to rotate the coordinate system + # of the axis and use that to rotate the object. + r = FreeCAD.Vector(v.y, v.z, v.x) + a = 180 + else: + r = v.cross(normal) # rotation axis + a = DraftVecUtils.angle(normal, v, r) * 180 / math.pi + PathLog.debug( + "oh boy: (%.2f, %.2f, %.2f) x (%.2f, %.2f, %.2f) -> (%.2f, %.2f, %.2f) -> %.2f" + % (v.x, v.y, v.z, normal.x, normal.y, normal.z, r.x, r.y, r.z, a) + ) Draft.rotate(sel.Object, a, axis=r) selObject = None diff --git a/src/Mod/Path/PathScripts/PathOpGui.py b/src/Mod/Path/PathScripts/PathOpGui.py index b850a0cbad..62d9d80080 100644 --- a/src/Mod/Path/PathScripts/PathOpGui.py +++ b/src/Mod/Path/PathScripts/PathOpGui.py @@ -219,8 +219,8 @@ class TaskPanelPage(object): return hasattr(self.form, "toolController") def setParent(self, parent): - '''setParent() ... used to transfer parent object link to child class. - Do not overwrite.''' + """setParent() ... used to transfer parent object link to child class. + Do not overwrite.""" self.parent = parent def onDirtyChanged(self, callback): diff --git a/src/Mod/Path/PathScripts/PathPocket.py b/src/Mod/Path/PathScripts/PathPocket.py index 6f60763279..2db07d5b36 100644 --- a/src/Mod/Path/PathScripts/PathPocket.py +++ b/src/Mod/Path/PathScripts/PathPocket.py @@ -544,7 +544,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket): avgCom ) # effectively treats avgCom as origin for each face. mag = math.sqrt( - adjCom.x ** 2 + adjCom.y ** 2 + adjCom.x**2 + adjCom.y**2 ) # adjCom.Length without Z values drctn = 0.0 # Determine direction of vector diff --git a/src/Mod/Path/PathScripts/PathPost.py b/src/Mod/Path/PathScripts/PathPost.py index 8a250532fe..52aba08b85 100644 --- a/src/Mod/Path/PathScripts/PathPost.py +++ b/src/Mod/Path/PathScripts/PathPost.py @@ -46,6 +46,7 @@ PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) translate = FreeCAD.Qt.translate + class _TempObject: Path = None Name = "Fixture" diff --git a/src/Mod/Path/PathScripts/PathPreferencesAdvanced.py b/src/Mod/Path/PathScripts/PathPreferencesAdvanced.py index a0616fab4f..cdac0a8a65 100644 --- a/src/Mod/Path/PathScripts/PathPreferencesAdvanced.py +++ b/src/Mod/Path/PathScripts/PathPreferencesAdvanced.py @@ -30,6 +30,7 @@ if False: else: PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) + class AdvancedPreferencesPage: def __init__(self, parent=None): self.form = FreeCADGui.PySideUic.loadUi(":preferences/Advanced.ui") @@ -63,9 +64,7 @@ class AdvancedPreferencesPage: self.form.WarningSuppressOpenCamLib.setChecked( PathPreferences.suppressOpenCamLibWarning() ) - self.form.WarningSuppressVelocity.setChecked( - PathPreferences.suppressVelocity() - ) + self.form.WarningSuppressVelocity.setChecked(PathPreferences.suppressVelocity()) self.updateSelection() def updateSelection(self, state=None): diff --git a/src/Mod/Path/PathScripts/PathStock.py b/src/Mod/Path/PathScripts/PathStock.py index b4eedbcf2c..2338061477 100644 --- a/src/Mod/Path/PathScripts/PathStock.py +++ b/src/Mod/Path/PathScripts/PathStock.py @@ -424,7 +424,7 @@ def CreateCylinder(job, radius=None, height=None, placement=None): obj.Height = height elif base: bb = shapeBoundBox(base.Group) - obj.Radius = math.sqrt(bb.XLength ** 2 + bb.YLength ** 2) / 2.0 + obj.Radius = math.sqrt(bb.XLength**2 + bb.YLength**2) / 2.0 obj.Height = max(bb.ZLength, 1) if placement: diff --git a/src/Mod/Path/PathScripts/PathSurface.py b/src/Mod/Path/PathScripts/PathSurface.py index 84b83e5051..70a040bec8 100644 --- a/src/Mod/Path/PathScripts/PathSurface.py +++ b/src/Mod/Path/PathScripts/PathSurface.py @@ -2097,7 +2097,7 @@ class ObjectSurface(PathOp.ObjectOp): hlim = bb.XMax # Compute max radius of stock, as it rotates, and rotational clearance & safe heights - self.bbRadius = math.sqrt(hlim ** 2 + vlim ** 2) + self.bbRadius = math.sqrt(hlim**2 + vlim**2) self.clearHeight = self.bbRadius + JOB.SetupSheet.ClearanceHeightOffset.Value self.safeHeight = self.bbRadius + JOB.SetupSheet.ClearanceHeightOffset.Value diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 7914c0a54c..fa46905689 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -827,7 +827,7 @@ def RtoIJ(startpoint, command): perp = chord.cross(Vector(0, 0, 1)) # use pythagoras to get the perp length - plength = math.sqrt(radius ** 2 - (chord.Length / 2) ** 2) + plength = math.sqrt(radius**2 - (chord.Length / 2) ** 2) perp.normalize() perp.scale(plength, plength, plength) diff --git a/src/Mod/Path/PathScripts/post/philips_post.py b/src/Mod/Path/PathScripts/post/philips_post.py index d001ada2a5..edc2d82c67 100644 --- a/src/Mod/Path/PathScripts/post/philips_post.py +++ b/src/Mod/Path/PathScripts/post/philips_post.py @@ -475,7 +475,7 @@ def export(objectslist, filename, argstring): i = c.Parameters["I"] # calculate the radius r j = c.Parameters["J"] - r = math.sqrt(i ** 2 + j ** 2) + r = math.sqrt(i**2 + j**2) if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX,