From aae9d645f28a33212c353d5b90c79bf42711ddf2 Mon Sep 17 00:00:00 2001 From: sliptonic Date: Fri, 21 Jan 2022 13:37:29 -0600 Subject: [PATCH 1/8] ZCorrect translation cleanup --- .../Path/PathScripts/PathDressupZCorrect.py | 169 ++++++++++++------ 1 file changed, 114 insertions(+), 55 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDressupZCorrect.py b/src/Mod/Path/PathScripts/PathDressupZCorrect.py index 347ad0a229..ac2091fd8c 100644 --- a/src/Mod/Path/PathScripts/PathDressupZCorrect.py +++ b/src/Mod/Path/PathScripts/PathDressupZCorrect.py @@ -30,11 +30,14 @@ import PathScripts.PathGeom as PathGeom import PathScripts.PathLog as PathLog import PathScripts.PathUtils as PathUtils -from PySide import QtCore, QtGui +from PySide import QtGui +from PySide.QtCore import QT_TRANSLATE_NOOP +from PathGeom import CmdMoveArc, CmdMoveStraight # lazily loaded modules from lazy_loader.lazy_loader import LazyLoader -Part = LazyLoader('Part', globals(), 'Part') + +Part = LazyLoader("Part", globals(), "Part") """Z Depth Correction Dressup. This dressup takes a probe file as input and does bilinear interpolation of the Zdepths to correct for a surface which is not parallel to the milling table/bed. The probe file should conform to the format specified by the linuxcnc G38 probe logging: 9-number coordinate consisting of XYZABCUVW http://linuxcnc.org/docs/html/gcode/g-code.html#gcode:g38 """ @@ -43,32 +46,51 @@ LOGLEVEL = False LOG_MODULE = PathLog.thisModule() -if LOGLEVEL: - PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE) +if False: + PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) PathLog.trackModule(PathLog.thisModule()) else: - PathLog.setLevel(PathLog.Level.NOTICE, LOG_MODULE) + PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) -# Qt translation handling -def translate(context, text, disambig=None): - return QtCore.QCoreApplication.translate(context, text, disambig) - - -movecommands = ['G1', 'G01', 'G2', 'G02', 'G3', 'G03'] -rapidcommands = ['G0', 'G00'] -arccommands = ['G2', 'G3', 'G02', 'G03'] +translate = FreeCAD.Qt.translate class ObjectDressup: - def __init__(self, obj): - obj.addProperty("App::PropertyLink", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The base path to modify")) - obj.addProperty("App::PropertyFile", "probefile", "ProbeData", QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrect", "The point file from the surface probing.")) + obj.addProperty( + "App::PropertyLink", + "Base", + "Path", + QT_TRANSLATE_NOOP("App::Property", "The base path to modify"), + ) + obj.addProperty( + "App::PropertyFile", + "probefile", + "ProbeData", + QT_TRANSLATE_NOOP( + "App::Property", "The point file from the surface probing." + ), + ) obj.Proxy = self obj.addProperty("Part::PropertyPartShape", "interpSurface", "Path") - obj.addProperty("App::PropertyDistance", "ArcInterpolate", "Interpolate", QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrect", "Deflection distance for arc interpolation")) - obj.addProperty("App::PropertyDistance", "SegInterpolate", "Interpolate", QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrectp", "break segments into smaller segments of this length.")) + obj.addProperty( + "App::PropertyDistance", + "ArcInterpolate", + "Interpolate", + QT_TRANSLATE_NOOP( + "App::Property", "Deflection distance for arc interpolation" + ), + ) + obj.addProperty( + "App::PropertyDistance", + "SegInterpolate", + "Interpolate", + QT_TRANSLATE_NOOP( + "App::Property", + "break segments into smaller segments of this length.", + ), + ) obj.ArcInterpolate = 0.1 obj.SegInterpolate = 1.0 @@ -95,12 +117,12 @@ class ObjectDressup: if filename == "": return - f1 = open(filename, 'r') + f1 = open(filename, "r") try: pointlist = [] for line in f1.readlines(): - if line == '\n': + if line == "\n": continue w = line.split() xval = round(float(w[0]), 2) @@ -148,32 +170,47 @@ class ObjectDressup: pathlist = obj.Base.Path.Commands newcommandlist = [] - currLocation = {'X': 0, 'Y': 0, 'Z': 0, 'F': 0} + currLocation = {"X": 0, "Y": 0, "Z": 0, "F": 0} for c in pathlist: PathLog.debug(c) PathLog.debug(" curLoc:{}".format(currLocation)) newparams = dict(c.Parameters) - zval = newparams.get("Z", currLocation['Z']) - if c.Name in movecommands: - curVec = FreeCAD.Vector(currLocation['X'], currLocation['Y'], currLocation['Z']) + zval = newparams.get("Z", currLocation["Z"]) + if c.Name in CmdMoveStraight + CmdMoveArc: + curVec = FreeCAD.Vector( + currLocation["X"], + currLocation["Y"], + currLocation["Z"], + ) arcwire = PathGeom.edgeForCmd(c, curVec) if arcwire is None: continue - if c.Name in arccommands: + if c.Name in CmdMoveArc: pointlist = arcwire.discretize(Deflection=curveD) else: disc_number = int(arcwire.Length / sampleD) if disc_number > 1: - pointlist = arcwire.discretize(Number=int(arcwire.Length / sampleD)) + pointlist = arcwire.discretize( + Number=int(arcwire.Length / sampleD) + ) else: pointlist = [v.Point for v in arcwire.Vertexes] for point in pointlist: - offset = self._bilinearInterpolate(surface, point.x, point.y) - newcommand = Path.Command("G1", {'X': point.x, 'Y': point.y, 'Z': point.z + offset}) + offset = self._bilinearInterpolate( + surface, point.x, point.y + ) + newcommand = Path.Command( + "G1", + { + "X": point.x, + "Y": point.y, + "Z": point.z + offset, + }, + ) newcommandlist.append(newcommand) currLocation.update(newcommand.Parameters) - currLocation['Z'] = zval + currLocation["Z"] = zval else: # Non Feed Command @@ -184,12 +221,13 @@ class ObjectDressup: class TaskPanel: - def __init__(self, obj): self.obj = obj self.form = FreeCADGui.PySideUic.loadUi(":/panels/ZCorrectEdit.ui") - FreeCAD.ActiveDocument.openTransaction(translate("Path_DressupZCorrect", "Edit Z Correction Dress-up")) - self.interpshape = FreeCAD.ActiveDocument.addObject("Part::Feature", "InterpolationSurface") + FreeCAD.ActiveDocument.openTransaction("Edit Z Correction Dress-up") + self.interpshape = FreeCAD.ActiveDocument.addObject( + "Part::Feature", "InterpolationSurface" + ) self.interpshape.Shape = obj.interpSurface self.interpshape.ViewObject.Transparency = 60 self.interpshape.ViewObject.ShapeColor = (1.00000, 1.00000, 0.01961) @@ -218,9 +256,9 @@ class TaskPanel: if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG: for obj in FreeCAD.ActiveDocument.Objects: - if obj.Name.startswith('Shape'): + if obj.Name.startswith("Shape"): FreeCAD.ActiveDocument.removeObject(obj.Name) - print('object name %s' % self.obj.Name) + print("object name %s" % self.obj.Name) if hasattr(self.obj.Proxy, "shapes"): PathLog.info("showing shapes attribute") for shapes in self.obj.Proxy.shapes.itervalues(): @@ -249,14 +287,18 @@ class TaskPanel: self.form.SetProbePointFileName.clicked.connect(self.SetProbePointFileName) def SetProbePointFileName(self): - filename = QtGui.QFileDialog.getOpenFileName(self.form, translate("Path_Probe", "Select Probe Point File"), None, translate("Path_Probe", "All Files (*.*)")) + filename = QtGui.QFileDialog.getOpenFileName( + self.form, + translate("Path_Probe", "Select Probe Point File"), + None, + translate("Path_Probe", "All Files (*.*)"), + ) if filename and filename[0]: self.obj.probefile = str(filename[0]) self.setFields() class ViewProviderDressup: - def __init__(self, vobj): vobj.Proxy = self @@ -289,7 +331,7 @@ class ViewProviderDressup: return None def onDelete(self, arg1=None, arg2=None): - '''this makes sure that the base operation is added back to the project and visible''' + """this makes sure that the base operation is added back to the project and visible""" FreeCADGui.ActiveDocument.getObject(arg1.Object.Base.Name).Visibility = True job = PathUtils.findParentJob(arg1.Object) job.Proxy.addOperation(arg1.Object.Base) @@ -298,18 +340,23 @@ class ViewProviderDressup: class CommandPathDressup: - def GetResources(self): - return {'Pixmap': 'Path_Dressup', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrect", "Z Depth Correction Dress-up"), - 'Accel': "", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrect", "Use Probe Map to correct Z depth")} + return { + "Pixmap": "Path_Dressup", + "MenuText": QT_TRANSLATE_NOOP( + "Path_DressupZCorrect", "Z Depth Correction Dress-up" + ), + "Accel": "", + "ToolTip": QT_TRANSLATE_NOOP( + "Path_DressupZCorrect", "Use Probe Map to correct Z depth" + ), + } def IsActive(self): if FreeCAD.ActiveDocument is not None: for o in FreeCAD.ActiveDocument.Objects: if o.Name[:3] == "Job": - return True + return True return False def Activated(self): @@ -317,32 +364,44 @@ class CommandPathDressup: # check that the selection contains exactly what we want selection = FreeCADGui.Selection.getSelection() if len(selection) != 1: - FreeCAD.Console.PrintError(translate("Path_Dressup", "Please select one path object\n")) + FreeCAD.Console.PrintError( + translate("Path_Dressup", "Please select one path object\n") + ) return if not selection[0].isDerivedFrom("Path::Feature"): - FreeCAD.Console.PrintError(translate("Path_Dressup", "The selected object is not a path\n")) + FreeCAD.Console.PrintError( + translate("Path_Dressup", "The selected object is not a path\n") + ) return if selection[0].isDerivedFrom("Path::FeatureCompoundPython"): - FreeCAD.Console.PrintError(translate("Path_Dressup", "Please select a Path object")) + FreeCAD.Console.PrintError( + translate("Path_Dressup", "Please select a Path object") + ) return # everything ok! - FreeCAD.ActiveDocument.openTransaction(translate("Path_DressupZCorrect", "Create Dress-up")) + FreeCAD.ActiveDocument.openTransaction("Create Dress-up") FreeCADGui.addModule("PathScripts.PathDressupZCorrect") FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "ZCorrectDressup")') - FreeCADGui.doCommand('PathScripts.PathDressupZCorrect.ObjectDressup(obj)') - FreeCADGui.doCommand('obj.Base = FreeCAD.ActiveDocument.' + selection[0].Name) - FreeCADGui.doCommand('PathScripts.PathDressupZCorrect.ViewProviderDressup(obj.ViewObject)') - FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') - FreeCADGui.doCommand('Gui.ActiveDocument.getObject(obj.Base.Name).Visibility = False') - FreeCADGui.doCommand('obj.ViewObject.Document.setEdit(obj.ViewObject, 0)') + FreeCADGui.doCommand( + 'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "ZCorrectDressup")' + ) + FreeCADGui.doCommand("PathScripts.PathDressupZCorrect.ObjectDressup(obj)") + FreeCADGui.doCommand("obj.Base = FreeCAD.ActiveDocument." + selection[0].Name) + FreeCADGui.doCommand( + "PathScripts.PathDressupZCorrect.ViewProviderDressup(obj.ViewObject)" + ) + FreeCADGui.doCommand("PathScripts.PathUtils.addToJob(obj)") + FreeCADGui.doCommand( + "Gui.ActiveDocument.getObject(obj.Base.Name).Visibility = False" + ) + FreeCADGui.doCommand("obj.ViewObject.Document.setEdit(obj.ViewObject, 0)") FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_DressupZCorrect', CommandPathDressup()) + FreeCADGui.addCommand("Path_DressupZCorrect", CommandPathDressup()) FreeCAD.Console.PrintLog("Loading PathDressup... done\n") From 931f4a2b8f0e8fa1ae38a1d397f86ddb0e21cf7a Mon Sep 17 00:00:00 2001 From: sliptonic Date: Fri, 21 Jan 2022 13:40:08 -0600 Subject: [PATCH 2/8] black --- .../Path/PathScripts/PathDressupAxisMap.py | 138 ++++++++++++------ 1 file changed, 93 insertions(+), 45 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDressupAxisMap.py b/src/Mod/Path/PathScripts/PathDressupAxisMap.py index 085d2b3b81..12cdcf914b 100644 --- a/src/Mod/Path/PathScripts/PathDressupAxisMap.py +++ b/src/Mod/Path/PathScripts/PathDressupAxisMap.py @@ -41,18 +41,34 @@ def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) -movecommands = ['G1', 'G01', 'G2', 'G02', 'G3', 'G03'] -rapidcommands = ['G0', 'G00'] -arccommands = ['G2', 'G3', 'G02', 'G03'] +movecommands = ["G1", "G01", "G2", "G02", "G3", "G03"] +rapidcommands = ["G0", "G00"] +arccommands = ["G2", "G3", "G02", "G03"] class ObjectDressup: - def __init__(self, obj): maplist = ["X->A", "Y->A", "X->B", "Y->B", "X->C", "Y->C"] - obj.addProperty("App::PropertyLink", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The base path to modify")) - obj.addProperty("App::PropertyEnumeration", "AxisMap", "Path", QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The input mapping axis")) - obj.addProperty("App::PropertyDistance", "Radius", "Path", QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The radius of the wrapped axis")) + obj.addProperty( + "App::PropertyLink", + "Base", + "Path", + QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The base path to modify"), + ) + obj.addProperty( + "App::PropertyEnumeration", + "AxisMap", + "Path", + QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The input mapping axis"), + ) + obj.addProperty( + "App::PropertyDistance", + "Radius", + "Path", + QtCore.QT_TRANSLATE_NOOP( + "Path_DressupAxisMap", "The radius of the wrapped axis" + ), + ) obj.AxisMap = maplist obj.AxisMap = "Y->A" obj.Proxy = self @@ -64,22 +80,26 @@ class ObjectDressup: return None def _linear2angular(self, radius, length): - '''returns an angular distance in degrees to achieve a linear move of a given lenth''' + """returns an angular distance in degrees to achieve a linear move of a given lenth""" circum = 2 * math.pi * float(radius) return 360 * (float(length) / circum) def _stripArcs(self, path, d): - '''converts all G2/G3 commands into G1 commands''' + """converts all G2/G3 commands into G1 commands""" newcommandlist = [] - currLocation = {'X': 0, 'Y': 0, 'Z': 0, 'F': 0} + currLocation = {"X": 0, "Y": 0, "Z": 0, "F": 0} for p in path: if p.Name in arccommands: - curVec = FreeCAD.Vector(currLocation['X'], currLocation['Y'], currLocation['Z']) + curVec = FreeCAD.Vector( + currLocation["X"], currLocation["Y"], currLocation["Z"] + ) arcwire = PathGeom.edgeForCmd(p, curVec) pointlist = arcwire.discretize(Deflection=d) for point in pointlist: - newcommand = Path.Command("G1", {'X': point.x, 'Y': point.y, 'Z': point.z}) + newcommand = Path.Command( + "G1", {"X": point.x, "Y": point.y, "Z": point.z} + ) newcommandlist.append(newcommand) currLocation.update(newcommand.Parameters) else: @@ -105,20 +125,28 @@ class ObjectDressup: pathlist = self._stripArcs(pp, d) newcommandlist = [] - currLocation = {'X': 0, 'Y': 0, 'Z': 0, 'F': 0} + currLocation = {"X": 0, "Y": 0, "Z": 0, "F": 0} for c in pathlist: newparams = dict(c.Parameters) remapvar = newparams.pop(inAxis, None) if remapvar is not None: - newparams[outAxis] = self._linear2angular(obj.Radius, remapvar) - locdiff = dict(set(newparams.items()) - set(currLocation.items())) - if len(locdiff) == 1 and outAxis in locdiff: # pure rotation. Calculate rotational feed rate - if 'F' in c.Parameters: - feed = c.Parameters['F'] + newparams[outAxis] = self._linear2angular( + obj.Radius, remapvar + ) + locdiff = dict( + set(newparams.items()) - set(currLocation.items()) + ) + if ( + len(locdiff) == 1 and outAxis in locdiff + ): # pure rotation. Calculate rotational feed rate + if "F" in c.Parameters: + feed = c.Parameters["F"] else: - feed = currLocation['F'] - newparams.update({"F": self._linear2angular(obj.Radius, feed)}) + feed = currLocation["F"] + newparams.update( + {"F": self._linear2angular(obj.Radius, feed)} + ) newcommand = Path.Command(c.Name, newparams) newcommandlist.append(newcommand) currLocation.update(newparams) @@ -131,7 +159,7 @@ class ObjectDressup: obj.Path = path def onChanged(self, obj, prop): - if 'Restore' not in obj.State and prop == "Radius": + if "Restore" not in obj.State and prop == "Radius": job = PathUtils.findParentJob(obj) if job: job.Proxy.setCenterOfRotation(self.center(obj)) @@ -141,12 +169,13 @@ class ObjectDressup: class TaskPanel: - def __init__(self, obj): self.obj = obj self.form = FreeCADGui.PySideUic.loadUi(":/panels/AxisMapEdit.ui") - self.radius = PathGui.QuantitySpinBox(self.form.radius, obj, 'Radius') - FreeCAD.ActiveDocument.openTransaction(translate("Path_DressupDragKnife", "Edit Dragknife Dress-up")) + self.radius = PathGui.QuantitySpinBox(self.form.radius, obj, "Radius") + FreeCAD.ActiveDocument.openTransaction( + translate("Path_DressupDragKnife", "Edit Dragknife Dress-up") + ) def reject(self): FreeCAD.ActiveDocument.abortTransaction() @@ -187,7 +216,6 @@ class TaskPanel: class ViewProviderDressup: - def __init__(self, vobj): self.obj = vobj.Object @@ -226,7 +254,7 @@ class ViewProviderDressup: return None def onDelete(self, arg1=None, arg2=None): - '''this makes sure that the base operation is added back to the project and visible''' + """this makes sure that the base operation is added back to the project and visible""" # pylint: disable=unused-argument if arg1.Object and arg1.Object.Base: FreeCADGui.ActiveDocument.getObject(arg1.Object.Base.Name).Visibility = True @@ -241,10 +269,16 @@ class CommandPathDressup: # pylint: disable=no-init def GetResources(self): - return {'Pixmap': 'Path_Dressup', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "Axis Map Dress-up"), - 'Accel': "", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "Remap one axis to another.")} + return { + "Pixmap": "Path_Dressup", + "MenuText": QtCore.QT_TRANSLATE_NOOP( + "Path_DressupAxisMap", "Axis Map Dress-up" + ), + "Accel": "", + "ToolTip": QtCore.QT_TRANSLATE_NOOP( + "Path_DressupAxisMap", "Remap one axis to another." + ), + } def IsActive(self): if FreeCAD.ActiveDocument is not None: @@ -258,35 +292,49 @@ class CommandPathDressup: # check that the selection contains exactly what we want selection = FreeCADGui.Selection.getSelection() if len(selection) != 1: - FreeCAD.Console.PrintError(translate("Path_Dressup", "Please select one path object\n")) + FreeCAD.Console.PrintError( + translate("Path_Dressup", "Please select one path object\n") + ) return if not selection[0].isDerivedFrom("Path::Feature"): - FreeCAD.Console.PrintError(translate("Path_Dressup", "The selected object is not a path\n")) + FreeCAD.Console.PrintError( + translate("Path_Dressup", "The selected object is not a path\n") + ) return if selection[0].isDerivedFrom("Path::FeatureCompoundPython"): - FreeCAD.Console.PrintError(translate("Path_Dressup", "Please select a Path object")) + FreeCAD.Console.PrintError( + translate("Path_Dressup", "Please select a Path object") + ) return # everything ok! - FreeCAD.ActiveDocument.openTransaction(translate("Path_DressupAxisMap", "Create Dress-up")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_DressupAxisMap", "Create Dress-up") + ) FreeCADGui.addModule("PathScripts.PathDressupAxisMap") FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "AxisMapDressup")') - FreeCADGui.doCommand('PathScripts.PathDressupAxisMap.ObjectDressup(obj)') - FreeCADGui.doCommand('base = FreeCAD.ActiveDocument.' + selection[0].Name) - FreeCADGui.doCommand('job = PathScripts.PathUtils.findParentJob(base)') - FreeCADGui.doCommand('obj.Base = base') - FreeCADGui.doCommand('obj.Radius = 45') - FreeCADGui.doCommand('job.Proxy.addOperation(obj, base)') - FreeCADGui.doCommand('obj.ViewObject.Proxy = PathScripts.PathDressupAxisMap.ViewProviderDressup(obj.ViewObject)') - FreeCADGui.doCommand('Gui.ActiveDocument.getObject(base.Name).Visibility = False') - FreeCADGui.doCommand('obj.ViewObject.Document.setEdit(obj.ViewObject, 0)') + FreeCADGui.doCommand( + 'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "AxisMapDressup")' + ) + FreeCADGui.doCommand("PathScripts.PathDressupAxisMap.ObjectDressup(obj)") + FreeCADGui.doCommand("base = FreeCAD.ActiveDocument." + selection[0].Name) + FreeCADGui.doCommand("job = PathScripts.PathUtils.findParentJob(base)") + FreeCADGui.doCommand("obj.Base = base") + FreeCADGui.doCommand("obj.Radius = 45") + FreeCADGui.doCommand("job.Proxy.addOperation(obj, base)") + FreeCADGui.doCommand( + "obj.ViewObject.Proxy = PathScripts.PathDressupAxisMap.ViewProviderDressup(obj.ViewObject)" + ) + FreeCADGui.doCommand( + "Gui.ActiveDocument.getObject(base.Name).Visibility = False" + ) + FreeCADGui.doCommand("obj.ViewObject.Document.setEdit(obj.ViewObject, 0)") FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_DressupAxisMap', CommandPathDressup()) + FreeCADGui.addCommand("Path_DressupAxisMap", CommandPathDressup()) FreeCAD.Console.PrintLog("Loading PathDressup... done\n") From 4c08365920aa51fb764f9de893ecc875296174c6 Mon Sep 17 00:00:00 2001 From: sliptonic Date: Fri, 21 Jan 2022 13:47:40 -0600 Subject: [PATCH 3/8] AxisMap dressup translation cleanup --- .../Path/PathScripts/PathDressupAxisMap.py | 45 ++++++++----------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDressupAxisMap.py b/src/Mod/Path/PathScripts/PathDressupAxisMap.py index 12cdcf914b..fa69fb9f68 100644 --- a/src/Mod/Path/PathScripts/PathDressupAxisMap.py +++ b/src/Mod/Path/PathScripts/PathDressupAxisMap.py @@ -26,8 +26,16 @@ import math import PathScripts.PathGeom as PathGeom import PathScripts.PathUtils as PathUtils import PathScripts.PathGui as PathGui +import PathScripts.PathLog as PathLog +from PySide.QtCore import QT_TRANSLATE_NOOP +from PathGeom import CmdMoveArc + +if False: + PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) + PathLog.trackModule(PathLog.thisModule()) +else: + PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) -from PySide import QtCore if FreeCAD.GuiUp: import FreeCADGui @@ -36,14 +44,7 @@ __doc__ = """Axis remapping Dressup object and FreeCAD command. This dressup re For example, you can re-map the Y axis to A to control a 4th axis rotary.""" -# Qt translation handling -def translate(context, text, disambig=None): - return QtCore.QCoreApplication.translate(context, text, disambig) - - -movecommands = ["G1", "G01", "G2", "G02", "G3", "G03"] -rapidcommands = ["G0", "G00"] -arccommands = ["G2", "G3", "G02", "G03"] +translate = FreeCAD.Qt.translate class ObjectDressup: @@ -53,21 +54,19 @@ class ObjectDressup: "App::PropertyLink", "Base", "Path", - QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The base path to modify"), + QT_TRANSLATE_NOOP("App::Property", "The base path to modify"), ) obj.addProperty( "App::PropertyEnumeration", "AxisMap", "Path", - QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The input mapping axis"), + QT_TRANSLATE_NOOP("App::Property", "The input mapping axis"), ) obj.addProperty( "App::PropertyDistance", "Radius", "Path", - QtCore.QT_TRANSLATE_NOOP( - "Path_DressupAxisMap", "The radius of the wrapped axis" - ), + QT_TRANSLATE_NOOP("App::Property", "The radius of the wrapped axis"), ) obj.AxisMap = maplist obj.AxisMap = "Y->A" @@ -90,7 +89,7 @@ class ObjectDressup: currLocation = {"X": 0, "Y": 0, "Z": 0, "F": 0} for p in path: - if p.Name in arccommands: + if p.Name in CmdMoveArc: curVec = FreeCAD.Vector( currLocation["X"], currLocation["Y"], currLocation["Z"] ) @@ -119,7 +118,7 @@ class ObjectDressup: if obj.Base.Path: if obj.Base.Path.Commands: pp = obj.Base.Path.Commands - if len([i for i in pp if i.Name in arccommands]) == 0: + if len([i for i in pp if i.Name in CmdMoveArc]) == 0: pathlist = pp else: pathlist = self._stripArcs(pp, d) @@ -173,9 +172,7 @@ class TaskPanel: self.obj = obj self.form = FreeCADGui.PySideUic.loadUi(":/panels/AxisMapEdit.ui") self.radius = PathGui.QuantitySpinBox(self.form.radius, obj, "Radius") - FreeCAD.ActiveDocument.openTransaction( - translate("Path_DressupDragKnife", "Edit Dragknife Dress-up") - ) + FreeCAD.ActiveDocument.openTransaction("Edit Dragknife Dress-up") def reject(self): FreeCAD.ActiveDocument.abortTransaction() @@ -271,11 +268,9 @@ class CommandPathDressup: def GetResources(self): return { "Pixmap": "Path_Dressup", - "MenuText": QtCore.QT_TRANSLATE_NOOP( - "Path_DressupAxisMap", "Axis Map Dress-up" - ), + "MenuText": QT_TRANSLATE_NOOP("Path_DressupAxisMap", "Axis Map Dress-up"), "Accel": "", - "ToolTip": QtCore.QT_TRANSLATE_NOOP( + "ToolTip": QT_TRANSLATE_NOOP( "Path_DressupAxisMap", "Remap one axis to another." ), } @@ -308,9 +303,7 @@ class CommandPathDressup: return # everything ok! - FreeCAD.ActiveDocument.openTransaction( - translate("Path_DressupAxisMap", "Create Dress-up") - ) + FreeCAD.ActiveDocument.openTransaction("Create Dress-up") FreeCADGui.addModule("PathScripts.PathDressupAxisMap") FreeCADGui.addModule("PathScripts.PathUtils") FreeCADGui.doCommand( From d39d91f90ef722ef95839a9aae129883d42416ed Mon Sep 17 00:00:00 2001 From: sliptonic Date: Fri, 21 Jan 2022 13:50:55 -0600 Subject: [PATCH 4/8] Black --- src/Mod/Path/PathScripts/PathVcarve.py | 191 ++++++++++++++-------- src/Mod/Path/PathScripts/PathVcarveGui.py | 53 +++--- 2 files changed, 159 insertions(+), 85 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathVcarve.py b/src/Mod/Path/PathScripts/PathVcarve.py index 27fbbee8ef..898f5faf1f 100644 --- a/src/Mod/Path/PathScripts/PathVcarve.py +++ b/src/Mod/Path/PathScripts/PathVcarve.py @@ -30,20 +30,18 @@ import PathScripts.PathUtils as PathUtils import PathScripts.PathGeom as PathGeom import PathScripts.PathPreferences as PathPreferences -import traceback - import math from PySide import QtCore __doc__ = "Class and implementation of Path Vcarve operation" -PRIMARY = 0 +PRIMARY = 0 SECONDARY = 1 EXTERIOR1 = 2 EXTERIOR2 = 3 -COLINEAR = 4 -TWIN = 5 +COLINEAR = 4 +TWIN = 5 PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) # PathLog.trackModule(PathLog.thisModule()) @@ -57,7 +55,7 @@ def translate(context, text, disambig=None): VD = [] Vertex = {} -_sorting = 'global' +_sorting = "global" def _collectVoronoiWires(vd): @@ -104,13 +102,13 @@ def _collectVoronoiWires(vd): we = [] vFirst = knots[0] vStart = vFirst - vLast = vFirst + vLast = vFirst if len(vertex[vStart]): while vStart is not None: - vLast = vStart - edges = vertex[vStart] + vLast = vStart + edges = vertex[vStart] if len(edges) > 0: - edge = edges[0] + edge = edges[0] vStart = traverse(vStart, edge, we) else: vStart = None @@ -133,11 +131,11 @@ def _sortVoronoiWires(wires, start=FreeCAD.Vector(0, 0, 0)): return (p, l) begin = {} - end = {} + end = {} for i, w in enumerate(wires): begin[i] = w[0].Vertices[0].toPoint() - end[i] = w[-1].Vertices[1].toPoint() + end[i] = w[-1].Vertices[1].toPoint() result = [] while begin: @@ -145,23 +143,24 @@ def _sortVoronoiWires(wires, start=FreeCAD.Vector(0, 0, 0)): (eIdx, eLen) = closestTo(start, end) if bLen < eLen: result.append(wires[bIdx]) - start = end[bIdx] - del begin[bIdx] - del end[bIdx] + start = end[bIdx] + del begin[bIdx] + del end[bIdx] else: result.append([e.Twin for e in reversed(wires[eIdx])]) start = begin[eIdx] - del begin[eIdx] - del end[eIdx] + del begin[eIdx] + del end[eIdx] return result + class _Geometry(object): - '''POD class so the limits only have to be calculated once.''' + """POD class so the limits only have to be calculated once.""" def __init__(self, zStart, zStop, zScale): self.start = zStart - self.stop = zStop + self.stop = zStop self.scale = zScale @classmethod @@ -170,8 +169,8 @@ class _Geometry(object): rMin = float(tool.TipDiameter) / 2.0 toolangle = math.tan(math.radians(tool.CuttingEdgeAngle.Value / 2.0)) zScale = 1.0 / toolangle - zStop = zStart - rMax * zScale - zOff = rMin * zScale + zStop = zStart - rMax * zScale + zOff = rMin * zScale return _Geometry(zStart + zOff, max(zStop + zOff, zFinal), zScale) @@ -182,45 +181,74 @@ class _Geometry(object): return cls.FromTool(obj.ToolController.Tool, zStart, finalDepth) + def _calculate_depth(MIC, geom): # given a maximum inscribed circle (MIC) and tool angle, # return depth of cut relative to zStart. depth = geom.start - round(MIC * geom.scale, 4) - PathLog.debug('zStart value: {} depth: {}'.format(geom.start, depth)) + PathLog.debug("zStart value: {} depth: {}".format(geom.start, depth)) return max(depth, geom.stop) + def _getPartEdge(edge, depths): dist = edge.getDistances() zBegin = _calculate_depth(dist[0], depths) - zEnd = _calculate_depth(dist[1], depths) + zEnd = _calculate_depth(dist[1], depths) return edge.toShape(zBegin, zEnd) + class ObjectVcarve(PathEngraveBase.ObjectOp): - '''Proxy class for Vcarve operation.''' + """Proxy class for Vcarve operation.""" def opFeatures(self, obj): - '''opFeatures(obj) ... return all standard features and edges based geomtries''' - return PathOp.FeatureTool | PathOp.FeatureHeights | PathOp.FeatureDepths | PathOp.FeatureBaseFaces | PathOp.FeatureCoolant + """opFeatures(obj) ... return all standard features and edges based geomtries""" + return ( + PathOp.FeatureTool + | PathOp.FeatureHeights + | PathOp.FeatureDepths + | PathOp.FeatureBaseFaces + | PathOp.FeatureCoolant + ) def setupAdditionalProperties(self, obj): - if not hasattr(obj, 'BaseShapes'): - obj.addProperty("App::PropertyLinkList", "BaseShapes", "Path", - QtCore.QT_TRANSLATE_NOOP("PathVcarve", - "Additional base objects to be engraved")) - obj.setEditorMode('BaseShapes', 2) # hide + if not hasattr(obj, "BaseShapes"): + obj.addProperty( + "App::PropertyLinkList", + "BaseShapes", + "Path", + QtCore.QT_TRANSLATE_NOOP( + "PathVcarve", "Additional base objects to be engraved" + ), + ) + obj.setEditorMode("BaseShapes", 2) # hide def initOperation(self, obj): - '''initOperation(obj) ... create vcarve specific properties.''' - obj.addProperty("App::PropertyFloat", "Discretize", "Path", - QtCore.QT_TRANSLATE_NOOP("PathVcarve", - "The deflection value for discretizing arcs")) - obj.addProperty("App::PropertyFloat", "Colinear", "Path", - QtCore.QT_TRANSLATE_NOOP("PathVcarve", - "Cutoff for removing colinear segments (degrees). \ - default=10.0.")) - obj.addProperty("App::PropertyFloat", "Tolerance", "Path", - QtCore.QT_TRANSLATE_NOOP("PathVcarve", "")) + """initOperation(obj) ... create vcarve specific properties.""" + obj.addProperty( + "App::PropertyFloat", + "Discretize", + "Path", + QtCore.QT_TRANSLATE_NOOP( + "PathVcarve", "The deflection value for discretizing arcs" + ), + ) + obj.addProperty( + "App::PropertyFloat", + "Colinear", + "Path", + QtCore.QT_TRANSLATE_NOOP( + "PathVcarve", + "Cutoff for removing colinear segments (degrees). \ + default=10.0.", + ), + ) + obj.addProperty( + "App::PropertyFloat", + "Tolerance", + "Path", + QtCore.QT_TRANSLATE_NOOP("PathVcarve", ""), + ) obj.Colinear = 10.0 obj.Discretize = 0.01 obj.Tolerance = PathPreferences.defaultGeometryTolerance() @@ -237,27 +265,31 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): return edges def buildPathMedial(self, obj, faces): - '''constructs a medial axis path using openvoronoi''' + """constructs a medial axis path using openvoronoi""" def insert_many_wires(vd, wires): for wire in wires: - PathLog.debug('discretize value: {}'.format(obj.Discretize)) + PathLog.debug("discretize value: {}".format(obj.Discretize)) pts = wire.discretize(QuasiDeflection=obj.Discretize) ptv = [FreeCAD.Vector(p.x, p.y) for p in pts] ptv.append(ptv[0]) for i in range(len(pts)): - vd.addSegment(ptv[i], ptv[i+1]) + vd.addSegment(ptv[i], ptv[i + 1]) def cutWire(edges): path = [] path.append(Path.Command("G0 Z{}".format(obj.SafeHeight.Value))) e = edges[0] p = e.valueAt(e.FirstParameter) - path.append(Path.Command("G0 X{} Y{} Z{}".format(p.x, p.y, obj.SafeHeight.Value))) + path.append( + Path.Command("G0 X{} Y{} Z{}".format(p.x, p.y, obj.SafeHeight.Value)) + ) hSpeed = obj.ToolController.HorizFeed.Value vSpeed = obj.ToolController.VertFeed.Value - path.append(Path.Command("G1 X{} Y{} Z{} F{}".format(p.x, p.y, p.z, vSpeed))) + path.append( + Path.Command("G1 X{} Y{} Z{} F{}".format(p.x, p.y, p.z, vSpeed)) + ) for e in edges: path.extend(PathGeom.cmdsForEdge(e, hSpeed=hSpeed, vSpeed=vSpeed)) @@ -274,19 +306,22 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): for e in vd.Edges: e.Color = PRIMARY if e.isPrimary() else SECONDARY vd.colorExterior(EXTERIOR1) - vd.colorExterior(EXTERIOR2, - lambda v: not f.isInside(v.toPoint(f.BoundBox.ZMin), - obj.Tolerance, True)) + vd.colorExterior( + EXTERIOR2, + lambda v: not f.isInside( + v.toPoint(f.BoundBox.ZMin), obj.Tolerance, True + ), + ) vd.colorColinear(COLINEAR, obj.Colinear) vd.colorTwins(TWIN) wires = _collectVoronoiWires(vd) - if _sorting != 'global': + if _sorting != "global": wires = _sortVoronoiWires(wires) voronoiWires.extend(wires) VD.append((f, vd, wires)) - if _sorting == 'global': + if _sorting == "global": voronoiWires = _sortVoronoiWires(voronoiWires) geom = _Geometry.FromObj(obj, self.model[0]) @@ -301,14 +336,23 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): self.commandlist = pathlist def opExecute(self, obj): - '''opExecute(obj) ... process engraving operation''' + """opExecute(obj) ... process engraving operation""" PathLog.track() if not hasattr(obj.ToolController.Tool, "CuttingEdgeAngle"): - PathLog.error(translate("Path_Vcarve", "VCarve requires an engraving cutter with CuttingEdgeAngle")) + PathLog.error( + translate( + "Path_Vcarve", + "VCarve requires an engraving cutter with CuttingEdgeAngle", + ) + ) if obj.ToolController.Tool.CuttingEdgeAngle >= 180.0: - PathLog.error(translate("Path_Vcarve", "Engraver Cutting Edge Angle must be < 180 degrees.")) + PathLog.error( + translate( + "Path_Vcarve", "Engraver Cutting Edge Angle must be < 180 degrees." + ) + ) return try: @@ -325,27 +369,39 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): if not faces: for model in self.model: - if model.isDerivedFrom('Sketcher::SketchObject') or model.isDerivedFrom('Part::Part2DObject'): + if model.isDerivedFrom( + "Sketcher::SketchObject" + ) or model.isDerivedFrom("Part::Part2DObject"): faces.extend(model.Shape.Faces) if faces: self.buildPathMedial(obj, faces) else: - PathLog.error(translate('PathVcarve', 'The Job Base Object has no engraveable element. Engraving operation will produce no output.')) + PathLog.error( + translate( + "PathVcarve", + "The Job Base Object has no engraveable element. Engraving operation will produce no output.", + ) + ) except Exception as e: - #PathLog.error(e) - #traceback.print_exc() - PathLog.error(translate('PathVcarve', 'Error processing Base object. Engraving operation will produce no output.')) - #raise e + # PathLog.error(e) + # traceback.print_exc() + PathLog.error( + translate( + "PathVcarve", + "Error processing Base object. Engraving operation will produce no output.", + ) + ) + # raise e def opUpdateDepths(self, obj, ignoreErrors=False): - '''updateDepths(obj) ... engraving is always done at the top most z-value''' + """updateDepths(obj) ... engraving is always done at the top most z-value""" job = PathUtils.findParentJob(obj) self.opSetDefaultValues(obj, job) def opSetDefaultValues(self, obj, job): - '''opSetDefaultValues(obj) ... set depths for vcarving''' + """opSetDefaultValues(obj) ... set depths for vcarving""" if PathOp.FeatureDepths & self.opFeatures(obj): if job and len(job.Model.Group) > 0: bb = job.Proxy.modelBoundBox(job) @@ -355,15 +411,20 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): obj.OpFinalDepth = -0.1 def isToolSupported(self, obj, tool): - '''isToolSupported(obj, tool) ... returns True if v-carve op can work with tool.''' - return hasattr(tool, 'Diameter') and hasattr(tool, 'CuttingEdgeAngle') and hasattr(tool, 'TipDiameter') + """isToolSupported(obj, tool) ... returns True if v-carve op can work with tool.""" + return ( + hasattr(tool, "Diameter") + and hasattr(tool, "CuttingEdgeAngle") + and hasattr(tool, "TipDiameter") + ) + def SetupProperties(): return ["Discretize"] def Create(name, obj=None, parentJob=None): - '''Create(name) ... Creates and returns a Vcarve operation.''' + """Create(name) ... Creates and returns a Vcarve operation.""" if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) obj.Proxy = ObjectVcarve(obj, name, parentJob) diff --git a/src/Mod/Path/PathScripts/PathVcarveGui.py b/src/Mod/Path/PathScripts/PathVcarveGui.py index a2daf6aac1..4cf0f99d63 100644 --- a/src/Mod/Path/PathScripts/PathVcarveGui.py +++ b/src/Mod/Path/PathScripts/PathVcarveGui.py @@ -22,7 +22,7 @@ import FreeCAD import FreeCADGui -import PathGui as PGui # ensure Path/Gui/Resources are loaded +import PathGui as PGui # ensure Path/Gui/Resources are loaded import PathScripts.PathVcarve as PathVcarve import PathScripts.PathLog as PathLog import PathScripts.PathOpGui as PathOpGui @@ -47,7 +47,7 @@ def translate(context, text, disambig=None): class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage): - '''Enhanced base geometry page to also allow special base objects.''' + """Enhanced base geometry page to also allow special base objects.""" def super(self): return super(TaskPanelBaseGeometryPage, self) @@ -60,16 +60,25 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage): job = PathUtils.findParentJob(self.obj) base = job.Proxy.resourceClone(job, sel.Object) if not base: - PathLog.notice((translate("Path", "%s is not a Base Model object of the job %s") + "\n") % (sel.Object.Label, job.Label)) + PathLog.notice( + ( + translate("Path", "%s is not a Base Model object of the job %s") + + "\n" + ) + % (sel.Object.Label, job.Label) + ) continue if base in shapes: - PathLog.notice((translate("Path", "Base shape %s already in the list") + "\n") % (sel.Object.Label)) + PathLog.notice( + (translate("Path", "Base shape %s already in the list") + "\n") + % (sel.Object.Label) + ) continue - if base.isDerivedFrom('Part::Part2DObject'): + if base.isDerivedFrom("Part::Part2DObject"): if sel.HasSubObjects: # selectively add some elements of the drawing to the Base for sub in sel.SubElementNames: - if 'Vertex' in sub: + if "Vertex" in sub: PathLog.info(translate("Path", "Ignoring vertex")) else: self.obj.Proxy.addBase(self.obj, base, sub) @@ -107,20 +116,22 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage): sub = item.data(self.super().DataObjectSub) if not sub: shapes.append(obj) - PathLog.debug("Setting new base shapes: %s -> %s" % (self.obj.BaseShapes, shapes)) + PathLog.debug( + "Setting new base shapes: %s -> %s" % (self.obj.BaseShapes, shapes) + ) self.obj.BaseShapes = shapes return self.super().updateBase() class TaskPanelOpPage(PathOpGui.TaskPanelPage): - '''Page controller class for the Vcarve operation.''' + """Page controller class for the Vcarve operation.""" def getForm(self): - '''getForm() ... returns UI''' + """getForm() ... returns UI""" return FreeCADGui.PySideUic.loadUi(":/panels/PageOpVcarveEdit.ui") def getFields(self, obj): - '''getFields(obj) ... transfers values from UI to obj's proprties''' + """getFields(obj) ... transfers values from UI to obj's proprties""" if obj.Discretize != self.form.discretize.value(): obj.Discretize = self.form.discretize.value() if obj.Colinear != self.form.colinearFilter.value(): @@ -129,14 +140,14 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): self.updateCoolant(obj, self.form.coolantController) def setFields(self, obj): - '''setFields(obj) ... transfers obj's property values to UI''' + """setFields(obj) ... transfers obj's property values to UI""" self.form.discretize.setValue(obj.Discretize) self.form.colinearFilter.setValue(obj.Colinear) self.setupToolController(obj, self.form.toolController) self.setupCoolant(obj, self.form.coolantController) def getSignalsForUpdate(self, obj): - '''getSignalsForUpdate(obj) ... return list of signals for updating obj''' + """getSignalsForUpdate(obj) ... return list of signals for updating obj""" signals = [] signals.append(self.form.discretize.editingFinished) signals.append(self.form.colinearFilter.editingFinished) @@ -145,16 +156,18 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): return signals def taskPanelBaseGeometryPage(self, obj, features): - '''taskPanelBaseGeometryPage(obj, features) ... return page for adding base geometries.''' + """taskPanelBaseGeometryPage(obj, features) ... return page for adding base geometries.""" return TaskPanelBaseGeometryPage(obj, features) -Command = PathOpGui.SetupOperation('Vcarve', - PathVcarve.Create, - TaskPanelOpPage, - 'Path_Vcarve', - QtCore.QT_TRANSLATE_NOOP("Path_Vcarve", "Vcarve"), - QtCore.QT_TRANSLATE_NOOP("Path_Vcarve", "Creates a medial line engraving path"), - PathVcarve.SetupProperties) +Command = PathOpGui.SetupOperation( + "Vcarve", + PathVcarve.Create, + TaskPanelOpPage, + "Path_Vcarve", + QtCore.QT_TRANSLATE_NOOP("Path_Vcarve", "Vcarve"), + QtCore.QT_TRANSLATE_NOOP("Path_Vcarve", "Creates a medial line engraving path"), + PathVcarve.SetupProperties, +) FreeCAD.Console.PrintLog("Loading PathVcarveGui... done\n") From b60a97f2b42a903c01fad51e7ddf950a84f155eb Mon Sep 17 00:00:00 2001 From: sliptonic Date: Fri, 21 Jan 2022 13:59:02 -0600 Subject: [PATCH 5/8] Vcarve translation cleanup --- src/Mod/Path/PathScripts/PathVcarve.py | 37 ++++++++++------------- src/Mod/Path/PathScripts/PathVcarveGui.py | 12 +++----- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathVcarve.py b/src/Mod/Path/PathScripts/PathVcarve.py index 898f5faf1f..2a86f3dff8 100644 --- a/src/Mod/Path/PathScripts/PathVcarve.py +++ b/src/Mod/Path/PathScripts/PathVcarve.py @@ -29,8 +29,9 @@ import PathScripts.PathOp as PathOp import PathScripts.PathUtils as PathUtils import PathScripts.PathGeom as PathGeom import PathScripts.PathPreferences as PathPreferences - import math +from PySide.QtCore import QT_TRANSLATE_NOOP + from PySide import QtCore @@ -43,14 +44,14 @@ EXTERIOR2 = 3 COLINEAR = 4 TWIN = 5 -PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) -# PathLog.trackModule(PathLog.thisModule()) +if False: + PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) + PathLog.trackModule(PathLog.thisModule()) +else: + PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) -# Qt translation handling -def translate(context, text, disambig=None): - return QtCore.QCoreApplication.translate(context, text, disambig) - +translate = FreeCAD.Qt.translate VD = [] Vertex = {} @@ -217,8 +218,8 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): "App::PropertyLinkList", "BaseShapes", "Path", - QtCore.QT_TRANSLATE_NOOP( - "PathVcarve", "Additional base objects to be engraved" + QT_TRANSLATE_NOOP( + "App::Property", "Additional base objects to be engraved" ), ) obj.setEditorMode("BaseShapes", 2) # hide @@ -229,16 +230,16 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): "App::PropertyFloat", "Discretize", "Path", - QtCore.QT_TRANSLATE_NOOP( - "PathVcarve", "The deflection value for discretizing arcs" + QT_TRANSLATE_NOOP( + "App::Property", "The deflection value for discretizing arcs" ), ) obj.addProperty( "App::PropertyFloat", "Colinear", "Path", - QtCore.QT_TRANSLATE_NOOP( - "PathVcarve", + QT_TRANSLATE_NOOP( + "App::Property", "Cutoff for removing colinear segments (degrees). \ default=10.0.", ), @@ -247,7 +248,7 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): "App::PropertyFloat", "Tolerance", "Path", - QtCore.QT_TRANSLATE_NOOP("PathVcarve", ""), + QT_TRANSLATE_NOOP("App::Property", "Vcarve Tolerance"), ) obj.Colinear = 10.0 obj.Discretize = 0.01 @@ -385,15 +386,9 @@ class ObjectVcarve(PathEngraveBase.ObjectOp): ) except Exception as e: - # PathLog.error(e) - # traceback.print_exc() PathLog.error( - translate( - "PathVcarve", - "Error processing Base object. Engraving operation will produce no output.", - ) + "Error processing Base object. Engraving operation will produce no output." ) - # raise e def opUpdateDepths(self, obj, ignoreErrors=False): """updateDepths(obj) ... engraving is always done at the top most z-value""" diff --git a/src/Mod/Path/PathScripts/PathVcarveGui.py b/src/Mod/Path/PathScripts/PathVcarveGui.py index 4cf0f99d63..c044763d71 100644 --- a/src/Mod/Path/PathScripts/PathVcarveGui.py +++ b/src/Mod/Path/PathScripts/PathVcarveGui.py @@ -27,23 +27,22 @@ import PathScripts.PathVcarve as PathVcarve import PathScripts.PathLog as PathLog import PathScripts.PathOpGui as PathOpGui import PathScripts.PathUtils as PathUtils - from PySide import QtCore, QtGui + __title__ = "Path Vcarve Operation UI" __author__ = "sliptonic (Brad Collette)" __url__ = "http://www.freecadweb.org" __doc__ = "Vcarve operation page controller and command implementation." + if False: PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) PathLog.trackModule(PathLog.thisModule()) else: PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) - -def translate(context, text, disambig=None): - return QtCore.QCoreApplication.translate(context, text, disambig) +translate = FreeCAD.Qt.translate class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage): @@ -70,8 +69,7 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage): continue if base in shapes: PathLog.notice( - (translate("Path", "Base shape %s already in the list") + "\n") - % (sel.Object.Label) + "Base shape %s already in the list".format(sel.Object.Label) ) continue if base.isDerivedFrom("Part::Part2DObject"): @@ -79,7 +77,7 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage): # selectively add some elements of the drawing to the Base for sub in sel.SubElementNames: if "Vertex" in sub: - PathLog.info(translate("Path", "Ignoring vertex")) + PathLog.info("Ignoring vertex") else: self.obj.Proxy.addBase(self.obj, base, sub) else: From 953a319edc9db0dfad1cfbdfebb45960dd7e0621 Mon Sep 17 00:00:00 2001 From: sliptonic Date: Fri, 21 Jan 2022 14:04:31 -0600 Subject: [PATCH 6/8] black --- src/Mod/Path/PathScripts/PathDrillingGui.py | 49 +++++++++++++-------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDrillingGui.py b/src/Mod/Path/PathScripts/PathDrillingGui.py index f18ae76e0c..8f2a381946 100644 --- a/src/Mod/Path/PathScripts/PathDrillingGui.py +++ b/src/Mod/Path/PathScripts/PathDrillingGui.py @@ -22,7 +22,7 @@ import FreeCAD import FreeCADGui -import PathGui as PGui # ensure Path/Gui/Resources are loaded +import PathGui as PGui # ensure Path/Gui/Resources are loaded import PathScripts.PathCircularHoleBaseGui as PathCircularHoleBaseGui import PathScripts.PathDrilling as PathDrilling import PathScripts.PathGui as PathGui @@ -47,13 +47,19 @@ else: class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): - '''Controller for the drilling operation's page''' + """Controller for the drilling operation's page""" def initPage(self, obj): # pylint: disable=attribute-defined-outside-init - self.peckDepthSpinBox = PathGui.QuantitySpinBox(self.form.peckDepth, obj, 'PeckDepth') - self.peckRetractSpinBox = PathGui.QuantitySpinBox(self.form.peckRetractHeight, obj, 'RetractHeight') - self.dwellTimeSpinBox = PathGui.QuantitySpinBox(self.form.dwellTime, obj, 'DwellTime') + self.peckDepthSpinBox = PathGui.QuantitySpinBox( + self.form.peckDepth, obj, "PeckDepth" + ) + self.peckRetractSpinBox = PathGui.QuantitySpinBox( + self.form.peckRetractHeight, obj, "RetractHeight" + ) + self.dwellTimeSpinBox = PathGui.QuantitySpinBox( + self.form.dwellTime, obj, "DwellTime" + ) def registerSignalHandlers(self, obj): self.form.peckEnabled.toggled.connect(self.form.peckDepth.setEnabled) @@ -76,17 +82,17 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): self.form.dwellTimelabel.setEnabled(True) def getForm(self): - '''getForm() ... return UI''' + """getForm() ... return UI""" return FreeCADGui.PySideUic.loadUi(":/panels/PageOpDrillingEdit.ui") - def updateQuantitySpinBoxes(self, index = None): + def updateQuantitySpinBoxes(self, index=None): # pylint: disable=unused-argument self.peckDepthSpinBox.updateSpinBox() self.peckRetractSpinBox.updateSpinBox() self.dwellTimeSpinBox.updateSpinBox() def getFields(self, obj): - '''setFields(obj) ... update obj's properties with values from the UI''' + """setFields(obj) ... update obj's properties with values from the UI""" PathLog.track() self.peckDepthSpinBox.updateProperty() self.peckRetractSpinBox.updateProperty() @@ -103,7 +109,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): self.updateCoolant(obj, self.form.coolantController) def setFields(self, obj): - '''setFields(obj) ... update UI with obj properties' values''' + """setFields(obj) ... update UI with obj properties' values""" PathLog.track() self.updateQuantitySpinBoxes() @@ -122,9 +128,8 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): self.setupToolController(obj, self.form.toolController) self.setupCoolant(obj, self.form.coolantController) - def getSignalsForUpdate(self, obj): - '''getSignalsForUpdate(obj) ... return list of signals which cause the receiver to update the model''' + """getSignalsForUpdate(obj) ... return list of signals which cause the receiver to update the model""" signals = [] signals.append(self.form.peckRetractHeight.editingFinished) @@ -139,15 +144,21 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): return signals def updateData(self, obj, prop): - if prop in ['PeckDepth', 'RetractHeight'] and not prop in ['Base', 'Disabled']: + if prop in ["PeckDepth", "RetractHeight"] and not prop in ["Base", "Disabled"]: self.updateQuantitySpinBoxes() -Command = PathOpGui.SetupOperation('Drilling', - PathDrilling.Create, - TaskPanelOpPage, - 'Path_Drilling', - QtCore.QT_TRANSLATE_NOOP("Path_Drilling", "Drilling"), - QtCore.QT_TRANSLATE_NOOP("Path_Drilling", "Creates a Path Drilling object from a features of a base object"), - PathDrilling.SetupProperties) + +Command = PathOpGui.SetupOperation( + "Drilling", + PathDrilling.Create, + TaskPanelOpPage, + "Path_Drilling", + QtCore.QT_TRANSLATE_NOOP("Path_Drilling", "Drilling"), + QtCore.QT_TRANSLATE_NOOP( + "Path_Drilling", + "Creates a Path Drilling object from a features of a base object", + ), + PathDrilling.SetupProperties, +) FreeCAD.Console.PrintLog("Loading PathDrillingGui... done\n") From fee8660bcf28f30bbcab53af7567db82a79359a9 Mon Sep 17 00:00:00 2001 From: sliptonic Date: Fri, 21 Jan 2022 14:23:36 -0600 Subject: [PATCH 7/8] Drilling translation cleanup --- src/Mod/Path/PathScripts/PathDrilling.py | 73 ++++++++++++++------- src/Mod/Path/PathScripts/PathDrillingGui.py | 33 ++++++++-- 2 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDrilling.py b/src/Mod/Path/PathScripts/PathDrilling.py index 4f845a145b..bd080f7e03 100644 --- a/src/Mod/Path/PathScripts/PathDrilling.py +++ b/src/Mod/Path/PathScripts/PathDrilling.py @@ -25,7 +25,6 @@ from __future__ import print_function from Generators import drill_generator as generator -from PySide import QtCore import FreeCAD import Part import Path @@ -35,6 +34,7 @@ import PathScripts.PathCircularHoleBase as PathCircularHoleBase import PathScripts.PathLog as PathLog import PathScripts.PathOp as PathOp import PathScripts.PathUtils as PathUtils +from PySide.QtCore import QT_TRANSLATE_NOOP __title__ = "Path Drilling Operation" __author__ = "sliptonic (Brad Collette)" @@ -42,21 +42,56 @@ __url__ = "https://www.freecadweb.org" __doc__ = "Path Drilling operation." __contributors__ = "IMBack!" - if False: PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) PathLog.trackModule(PathLog.thisModule()) else: PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) -# Qt translation handling -def translate(context, text, disambig=None): - return QtCore.QCoreApplication.translate(context, text, disambig) +translate = FreeCAD.Qt.translate class ObjectDrilling(PathCircularHoleBase.ObjectOp): """Proxy object for Drilling operation.""" + @classmethod + def propertyEnumerations(self, dataType="data"): + """helixOpPropertyEnumerations(dataType="data")... return property enumeration lists of specified dataType. + Args: + dataType = 'data', 'raw', 'translated' + Notes: + 'data' is list of internal string literals used in code + 'raw' is list of (translated_text, data_string) tuples + 'translated' is list of translated string literals + """ + + # Enumeration lists for App::PropertyEnumeration properties + enums = { + "ReturnLevel": [ + (translate("Path_Drilling", "G99"), "G99"), + (translate("Path_Drilling", "G98"), "G98"), + ], # How high to retract after a drilling move + "ExtraOffset": [ + (translate("Path_Drilling", "None"), "None"), + (translate("Path_Drilling", "Drill Tip"), "Drill Tip"), + (translate("Path_Drilling", "2x Drill Tip"), "2x Drill Tip"), + ], # extra drilling depth to clear drill taper + } + + if dataType == "raw": + return enums + + data = list() + idx = 0 if dataType == "translated" else 1 + + PathLog.debug(enums) + + for k, v in enumerate(enums): + data.append((v, [tup[idx] for tup in enums[v]])) + PathLog.debug(data) + + return data + def circularHoleFeatures(self, obj): """circularHoleFeatures(obj) ... drilling works on anything, turn on all Base geometries and Locations.""" return ( @@ -69,7 +104,7 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp): "App::PropertyLength", "PeckDepth", "Drill", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Incremental Drill depth before retracting to clear chips", ), @@ -78,27 +113,25 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp): "App::PropertyBool", "PeckEnabled", "Drill", - QtCore.QT_TRANSLATE_NOOP("App::Property", "Enable pecking"), + QT_TRANSLATE_NOOP("App::Property", "Enable pecking"), ) obj.addProperty( "App::PropertyFloat", "DwellTime", "Drill", - QtCore.QT_TRANSLATE_NOOP( - "App::Property", "The time to dwell between peck cycles" - ), + QT_TRANSLATE_NOOP("App::Property", "The time to dwell between peck cycles"), ) obj.addProperty( "App::PropertyBool", "DwellEnabled", "Drill", - QtCore.QT_TRANSLATE_NOOP("App::Property", "Enable dwell"), + QT_TRANSLATE_NOOP("App::Property", "Enable dwell"), ) obj.addProperty( "App::PropertyBool", "AddTipLength", "Drill", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Calculate the tip length and subtract from final depth", ), @@ -107,7 +140,7 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp): "App::PropertyEnumeration", "ReturnLevel", "Drill", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Controls how tool retracts Default=G99" ), ) @@ -115,7 +148,7 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp): "App::PropertyDistance", "RetractHeight", "Drill", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "The height where feed starts and height during retract tool when path is finished while in a peck operation", ), @@ -124,17 +157,11 @@ class ObjectDrilling(PathCircularHoleBase.ObjectOp): "App::PropertyEnumeration", "ExtraOffset", "Drill", - QtCore.QT_TRANSLATE_NOOP( - "App::Property", "How far the drill depth is extended" - ), + QT_TRANSLATE_NOOP("App::Property", "How far the drill depth is extended"), ) - obj.ReturnLevel = ["G99", "G98"] # Canned Cycle Return Level - obj.ExtraOffset = [ - "None", - "Drill Tip", - "2x Drill Tip", - ] # Canned Cycle Return Level + for n in self.propertyEnumerations(): + setattr(obj, n[0], n[1]) def circularHoleExecute(self, obj, holes): """circularHoleExecute(obj, holes) ... generate drill operation for each hole in holes.""" diff --git a/src/Mod/Path/PathScripts/PathDrillingGui.py b/src/Mod/Path/PathScripts/PathDrillingGui.py index 8f2a381946..8e1b34ae46 100644 --- a/src/Mod/Path/PathScripts/PathDrillingGui.py +++ b/src/Mod/Path/PathScripts/PathDrillingGui.py @@ -37,13 +37,11 @@ __url__ = "https://www.freecadweb.org" __doc__ = "UI and Command for Path Drilling Operation." __contributors__ = "IMBack!" -LOGLEVEL = False - -if LOGLEVEL: +if False: PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) PathLog.trackModule(PathLog.thisModule()) else: - PathLog.setLevel(PathLog.Level.NOTICE, PathLog.thisModule()) + PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): @@ -83,7 +81,28 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): def getForm(self): """getForm() ... return UI""" - return FreeCADGui.PySideUic.loadUi(":/panels/PageOpDrillingEdit.ui") + form = FreeCADGui.PySideUic.loadUi(":/panels/PageOpDrillingEdit.ui") + + comboToPropertyMap = [("ExtraOffset", "ExtraOffset")] + enumTups = PathDrilling.ObjectDrilling.propertyEnumerations(dataType="raw") + self.populateCombobox(form, enumTups, comboToPropertyMap) + + return form + + def populateCombobox(self, form, enumTups, comboBoxesPropertyMap): + """fillComboboxes(form, comboBoxesPropertyMap) ... populate comboboxes with translated enumerations + ** comboBoxesPropertyMap will be unnecessary if UI files use strict combobox naming protocol. + Args: + form = UI form + enumTups = list of (translated_text, data_string) tuples + comboBoxesPropertyMap = list of (translated_text, data_string) tuples + """ + # Load appropriate enumerations in each combobox + for cb, prop in comboBoxesPropertyMap: + box = getattr(form, cb) # Get the combobox + box.clear() # clear the combobox + for text, data in enumTups[prop]: # load enumerations + box.addItem(text, data) def updateQuantitySpinBoxes(self, index=None): # pylint: disable=unused-argument @@ -102,8 +121,8 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage): obj.DwellEnabled = self.form.dwellEnabled.isChecked() if obj.PeckEnabled != self.form.peckEnabled.isChecked(): obj.PeckEnabled = self.form.peckEnabled.isChecked() - if obj.ExtraOffset != str(self.form.ExtraOffset.currentText()): - obj.ExtraOffset = str(self.form.ExtraOffset.currentText()) + if obj.ExtraOffset != str(self.form.ExtraOffset.currentData()): + obj.ExtraOffset = str(self.form.ExtraOffset.currentData()) self.updateToolController(obj, self.form.toolController) self.updateCoolant(obj, self.form.coolantController) From 2c2e13c178d2c32b9f7c0f9e6d433abba946bad3 Mon Sep 17 00:00:00 2001 From: sliptonic Date: Fri, 21 Jan 2022 14:30:40 -0600 Subject: [PATCH 8/8] import error --- src/Mod/Path/PathScripts/PathDressupAxisMap.py | 2 +- src/Mod/Path/PathScripts/PathDressupZCorrect.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDressupAxisMap.py b/src/Mod/Path/PathScripts/PathDressupAxisMap.py index fa69fb9f68..7ce73ab9e1 100644 --- a/src/Mod/Path/PathScripts/PathDressupAxisMap.py +++ b/src/Mod/Path/PathScripts/PathDressupAxisMap.py @@ -28,7 +28,7 @@ import PathScripts.PathUtils as PathUtils import PathScripts.PathGui as PathGui import PathScripts.PathLog as PathLog from PySide.QtCore import QT_TRANSLATE_NOOP -from PathGeom import CmdMoveArc +from PathScripts.PathGeom import CmdMoveArc if False: PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) diff --git a/src/Mod/Path/PathScripts/PathDressupZCorrect.py b/src/Mod/Path/PathScripts/PathDressupZCorrect.py index ac2091fd8c..1e70a04b31 100644 --- a/src/Mod/Path/PathScripts/PathDressupZCorrect.py +++ b/src/Mod/Path/PathScripts/PathDressupZCorrect.py @@ -32,7 +32,7 @@ import PathScripts.PathUtils as PathUtils from PySide import QtGui from PySide.QtCore import QT_TRANSLATE_NOOP -from PathGeom import CmdMoveArc, CmdMoveStraight +from PathScripts.PathGeom import CmdMoveArc, CmdMoveStraight # lazily loaded modules from lazy_loader.lazy_loader import LazyLoader