From d04f7909a35a2dcf5e81bee05a3758e6dcdc46a0 Mon Sep 17 00:00:00 2001 From: sliptonic Date: Sat, 22 Jan 2022 17:30:09 -0600 Subject: [PATCH] Adaptive translation cleanup --- src/Mod/Path/Gui/Resources/Path.qrc | 1 + .../Resources/panels/PageOpAdaptiveEdit.ui | 276 +++++++ src/Mod/Path/PathScripts/PathAdaptive.py | 776 ++++++++++++++---- src/Mod/Path/PathScripts/PathAdaptiveGui.py | 203 ++--- .../PathScripts/PathPreferencesAdvanced.py | 41 +- 5 files changed, 982 insertions(+), 315 deletions(-) create mode 100644 src/Mod/Path/Gui/Resources/panels/PageOpAdaptiveEdit.ui diff --git a/src/Mod/Path/Gui/Resources/Path.qrc b/src/Mod/Path/Gui/Resources/Path.qrc index 2921825c45..a8af95e4a4 100644 --- a/src/Mod/Path/Gui/Resources/Path.qrc +++ b/src/Mod/Path/Gui/Resources/Path.qrc @@ -105,6 +105,7 @@ panels/PageDepthsEdit.ui panels/PageDiametersEdit.ui panels/PageHeightsEdit.ui + panels/PageOpAdaptiveEdit.ui panels/PageOpCustomEdit.ui panels/PageOpDeburrEdit.ui panels/PageOpDrillingEdit.ui diff --git a/src/Mod/Path/Gui/Resources/panels/PageOpAdaptiveEdit.ui b/src/Mod/Path/Gui/Resources/panels/PageOpAdaptiveEdit.ui new file mode 100644 index 0000000000..dde5b650e4 --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/PageOpAdaptiveEdit.ui @@ -0,0 +1,276 @@ + + + Form + + + + 0 + 0 + 437 + 764 + + + + Form + + + + + + + + + Tool Controller + + + + + + + + + + Coolant + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + <html><head/><body><p>How much to lift the tool up during the rapid linking moves over cleared regions.</p><p>If linking path is not clear tool is raised to clearence height.</p></body></html> + + + + + + + Lift Distance + + + + + + + <html><head/><body><p>If &gt;0 it limits the helix ramp diameter</p><p>otherwise the 75 percent of tool diameter is used</p></body></html> + + + + + + + Helix Ramp Angle + + + + + + + <html><head/><body><p>Angle of the helix entry cone</p></body></html> + + + + + + + Stock to Leave + + + + + + + Cut Region + + + + + + + <html><head/><body><p>Cut inside or outside of the selected shapes</p></body></html> + + + + + + + Step Over Percent + + + + + + + Use Outline + + + + + + + <html><head/><body><p>Max length of keep-tool-down linking path compared to direct distance between points.</p><p>If exceeded link will be done by raising the tool to clearence height.</p></body></html> + + + + + + + Helix Max Diameter + + + + + + + Helix Cone Angle + + + + + + + Keep Tool Down Ratio + + + + + + + <html><head/><body><p>How much material to leave (i.e. for finishing operation)</p></body></html> + + + + + + + Force Clearing Inside-out + + + + + + + Operation Type + + + + + + + <html><head/><body><p>Angle of the helix ramp entry</p></body></html> + + + + + + + Finishing Profile + + + + + + + <html><head/><body><p>Type of adaptive operation</p></body></html> + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Accuracy vs Performance + + + + + + + <html><head/><body><p>Influences calculation performance vs stability and accuracy</p></body></html> + + + 5 + + + 15 + + + 10 + + + 10 + + + Qt::Horizontal + + + 1 + + + + + + + + + + <html><head/><body><p>Optimal value for tool stepover</p></body></html> + + + 1 + + + 100 + + + + + + + + + + Stop + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/Mod/Path/PathScripts/PathAdaptive.py b/src/Mod/Path/PathScripts/PathAdaptive.py index 42a6a9dbee..f7241105d0 100644 --- a/src/Mod/Path/PathScripts/PathAdaptive.py +++ b/src/Mod/Path/PathScripts/PathAdaptive.py @@ -32,17 +32,7 @@ import time import json import math import area - -from PySide import QtCore - -# lazily loaded modules -from lazy_loader.lazy_loader import LazyLoader -Part = LazyLoader('Part', globals(), 'Part') -# TechDraw = LazyLoader('TechDraw', globals(), 'TechDraw') -FeatureExtensions = LazyLoader('PathScripts.PathFeatureExtensions', - globals(), - 'PathScripts.PathFeatureExtensions') -DraftGeomUtils = LazyLoader('DraftGeomUtils', globals(), 'DraftGeomUtils') +from PySide.QtCore import QT_TRANSLATE_NOOP if FreeCAD.GuiUp: from pivy import coin @@ -50,14 +40,25 @@ if FreeCAD.GuiUp: __doc__ = "Class and implementation of the Adaptive path operation." +# lazily loaded modules +from lazy_loader.lazy_loader import LazyLoader -PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) -# PathLog.trackModule(PathLog.thisModule()) +Part = LazyLoader("Part", globals(), "Part") +# TechDraw = LazyLoader('TechDraw', globals(), 'TechDraw') +FeatureExtensions = LazyLoader( + "PathScripts.PathFeatureExtensions", globals(), "PathScripts.PathFeatureExtensions" +) +DraftGeomUtils = LazyLoader("DraftGeomUtils", globals(), "DraftGeomUtils") -# Qt translation handling -def translate(context, text, disambig=None): - return QtCore.QCoreApplication.translate(context, text, disambig) +if False: + PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) + PathLog.trackModule(PathLog.thisModule()) +else: + PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) + + +translate = FreeCAD.Qt.translate def convertTo2d(pathArray): @@ -112,11 +113,11 @@ def discretize(edge, flipDirection=False): def CalcHelixConePoint(height, cur_z, radius, angle): - x = ((height - cur_z) / height) * radius * math.cos(math.radians(angle)*cur_z) - y = ((height - cur_z) / height) * radius * math.sin(math.radians(angle)*cur_z) + x = ((height - cur_z) / height) * radius * math.cos(math.radians(angle) * cur_z) + y = ((height - cur_z) / height) * radius * math.sin(math.radians(angle) * cur_z) z = cur_z - return {'X': x, 'Y': y, 'Z': z} + return {"X": x, "Y": y, "Z": z} def GenerateGCode(op, obj, adaptiveResults, helixDiameter): @@ -129,7 +130,9 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): for region in adaptiveResults: p1 = region["HelixCenterPoint"] p2 = region["StartPoint"] - r = math.sqrt((p1[0]-p2[0]) * (p1[0]-p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1])) + r = math.sqrt( + (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]) + ) if r > helixRadius: helixRadius = r @@ -139,7 +142,7 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): if stepDown < 0.1: stepDown = 0.1 - length = 2*math.pi * helixRadius + length = 2 * math.pi * helixRadius if float(obj.HelixAngle) < 1: obj.HelixAngle = 1 @@ -162,13 +165,14 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): finish_step = stepDown depth_params = PathUtils.depth_params( - clearance_height=obj.ClearanceHeight.Value, - safe_height=obj.SafeHeight.Value, - start_depth=obj.StartDepth.Value, - step_down=stepDown, - z_finish_step=finish_step, - final_depth=obj.FinalDepth.Value, - user_depths=None) + clearance_height=obj.ClearanceHeight.Value, + safe_height=obj.SafeHeight.Value, + start_depth=obj.StartDepth.Value, + step_down=stepDown, + z_finish_step=finish_step, + final_depth=obj.FinalDepth.Value, + user_depths=None, + ) # ml: this is dangerous because it'll hide all unused variables hence forward # however, I don't know what lx and ly signify so I'll leave them for now @@ -182,16 +186,21 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): step = step + 1 for region in adaptiveResults: - startAngle = math.atan2(region["StartPoint"][1] - region["HelixCenterPoint"][1], region["StartPoint"][0] - region["HelixCenterPoint"][0]) + startAngle = math.atan2( + region["StartPoint"][1] - region["HelixCenterPoint"][1], + region["StartPoint"][0] - region["HelixCenterPoint"][0], + ) # lx = region["HelixCenterPoint"][0] # ly = region["HelixCenterPoint"][1] - passDepth = (passStartDepth - passEndDepth) + passDepth = passStartDepth - passEndDepth p1 = region["HelixCenterPoint"] p2 = region["StartPoint"] - helixRadius = math.sqrt((p1[0]-p2[0]) * (p1[0]-p2[0]) + (p1[1]-p2[1]) * (p1[1]-p2[1])) + helixRadius = math.sqrt( + (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]) + ) # Helix ramp if helixRadius > 0.01: @@ -199,43 +208,96 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): maxfi = passDepth / depthPerOneCircle * 2 * math.pi fi = 0 - offsetFi = -maxfi + startAngle-math.pi/16 + offsetFi = -maxfi + startAngle - math.pi / 16 - helixStart = [region["HelixCenterPoint"][0] + r * math.cos(offsetFi), region["HelixCenterPoint"][1] + r * math.sin(offsetFi)] + helixStart = [ + region["HelixCenterPoint"][0] + r * math.cos(offsetFi), + region["HelixCenterPoint"][1] + r * math.sin(offsetFi), + ] - op.commandlist.append(Path.Command("(Helix to depth: %f)" % passEndDepth)) + op.commandlist.append( + Path.Command("(Helix to depth: %f)" % passEndDepth) + ) if obj.UseHelixArcs is False: # rapid move to start point - op.commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value})) - op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.ClearanceHeight.Value})) + op.commandlist.append( + Path.Command("G0", {"Z": obj.ClearanceHeight.Value}) + ) + op.commandlist.append( + Path.Command( + "G0", + { + "X": helixStart[0], + "Y": helixStart[1], + "Z": obj.ClearanceHeight.Value, + }, + ) + ) # rapid move to safe height - op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.SafeHeight.Value})) + op.commandlist.append( + Path.Command( + "G0", + { + "X": helixStart[0], + "Y": helixStart[1], + "Z": obj.SafeHeight.Value, + }, + ) + ) # move to start depth - op.commandlist.append(Path.Command("G1", {"X": helixStart[0], "Y": helixStart[1], "Z": passStartDepth, "F": op.vertFeed})) + op.commandlist.append( + Path.Command( + "G1", + { + "X": helixStart[0], + "Y": helixStart[1], + "Z": passStartDepth, + "F": op.vertFeed, + }, + ) + ) if obj.HelixConeAngle == 0: while fi < maxfi: - x = region["HelixCenterPoint"][0] + r * math.cos(fi+offsetFi) - y = region["HelixCenterPoint"][1] + r * math.sin(fi+offsetFi) - z = passStartDepth - fi / maxfi * (passStartDepth - passEndDepth) - op.commandlist.append(Path.Command("G1", {"X": x, "Y": y, "Z": z, "F": op.vertFeed})) + x = region["HelixCenterPoint"][0] + r * math.cos( + fi + offsetFi + ) + y = region["HelixCenterPoint"][1] + r * math.sin( + fi + offsetFi + ) + z = passStartDepth - fi / maxfi * ( + passStartDepth - passEndDepth + ) + op.commandlist.append( + Path.Command( + "G1", {"X": x, "Y": y, "Z": z, "F": op.vertFeed} + ) + ) # lx = x # ly = y fi = fi + math.pi / 16 # one more circle at target depth to make sure center is cleared - maxfi = maxfi + 2*math.pi + maxfi = maxfi + 2 * math.pi while fi < maxfi: - x = region["HelixCenterPoint"][0] + r * math.cos(fi+offsetFi) - y = region["HelixCenterPoint"][1] + r * math.sin(fi+offsetFi) + x = region["HelixCenterPoint"][0] + r * math.cos( + fi + offsetFi + ) + y = region["HelixCenterPoint"][1] + r * math.sin( + fi + offsetFi + ) z = passEndDepth - op.commandlist.append(Path.Command("G1", {"X": x, "Y": y, "Z": z, "F": op.horizFeed})) + op.commandlist.append( + Path.Command( + "G1", {"X": x, "Y": y, "Z": z, "F": op.horizFeed} + ) + ) # lx = x # ly = y - fi = fi + math.pi/16 + fi = fi + math.pi / 16 else: # Cone @@ -248,9 +310,14 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): # Calculate everything helix_height = passStartDepth - passEndDepth - r_extra = helix_height * math.tan(math.radians(obj.HelixConeAngle)) + r_extra = helix_height * math.tan( + math.radians(obj.HelixConeAngle) + ) HelixTopRadius = helixRadius + r_extra - helix_full_height = HelixTopRadius * (math.cos(math.radians(obj.HelixConeAngle)) / math.sin(math.radians(obj.HelixConeAngle))) + helix_full_height = HelixTopRadius * ( + math.cos(math.radians(obj.HelixConeAngle)) + / math.sin(math.radians(obj.HelixConeAngle)) + ) # Start height z = passStartDepth @@ -267,70 +334,250 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): p = None # Calculate conical helix - while(z >= passEndDepth): + while z >= passEndDepth: if z < passEndDepth: z = passEndDepth - p = CalcHelixConePoint(helix_full_height, i, HelixTopRadius, _HelixAngle) - op.commandlist.append(Path.Command("G1", {"X": p['X'] + region["HelixCenterPoint"][0], "Y": p['Y'] + region["HelixCenterPoint"][1], "Z": z, "F": op.vertFeed})) + p = CalcHelixConePoint( + helix_full_height, i, HelixTopRadius, _HelixAngle + ) + op.commandlist.append( + Path.Command( + "G1", + { + "X": p["X"] + region["HelixCenterPoint"][0], + "Y": p["Y"] + region["HelixCenterPoint"][1], + "Z": z, + "F": op.vertFeed, + }, + ) + ) z = z - z_step i = i + z_step # Calculate some stuff for arcs at bottom - p['X'] = p['X'] + region["HelixCenterPoint"][0] - p['Y'] = p['Y'] + region["HelixCenterPoint"][1] - x_m = region["HelixCenterPoint"][0] - p['X'] + region["HelixCenterPoint"][0] - y_m = region["HelixCenterPoint"][1] - p['Y'] + region["HelixCenterPoint"][1] - i_off = (x_m - p['X']) / 2 - j_off = (y_m - p['Y']) / 2 + p["X"] = p["X"] + region["HelixCenterPoint"][0] + p["Y"] = p["Y"] + region["HelixCenterPoint"][1] + x_m = ( + region["HelixCenterPoint"][0] + - p["X"] + + region["HelixCenterPoint"][0] + ) + y_m = ( + region["HelixCenterPoint"][1] + - p["Y"] + + region["HelixCenterPoint"][1] + ) + i_off = (x_m - p["X"]) / 2 + j_off = (y_m - p["Y"]) / 2 # One more circle at target depth to make sure center is cleared - op.commandlist.append(Path.Command("G3", {"X": x_m, "Y": y_m, "Z": passEndDepth, "I": i_off, "J": j_off, "F": op.horizFeed})) - op.commandlist.append(Path.Command("G3", {"X": p['X'], "Y": p['Y'], "Z": passEndDepth, "I": -i_off, "J": -j_off, "F": op.horizFeed})) + op.commandlist.append( + Path.Command( + "G3", + { + "X": x_m, + "Y": y_m, + "Z": passEndDepth, + "I": i_off, + "J": j_off, + "F": op.horizFeed, + }, + ) + ) + op.commandlist.append( + Path.Command( + "G3", + { + "X": p["X"], + "Y": p["Y"], + "Z": passEndDepth, + "I": -i_off, + "J": -j_off, + "F": op.horizFeed, + }, + ) + ) else: # Use arcs for helix - no conical shape support - helixStart = [region["HelixCenterPoint"][0] + r, region["HelixCenterPoint"][1]] + helixStart = [ + region["HelixCenterPoint"][0] + r, + region["HelixCenterPoint"][1], + ] # rapid move to start point - op.commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value})) - op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.ClearanceHeight.Value})) + op.commandlist.append( + Path.Command("G0", {"Z": obj.ClearanceHeight.Value}) + ) + op.commandlist.append( + Path.Command( + "G0", + { + "X": helixStart[0], + "Y": helixStart[1], + "Z": obj.ClearanceHeight.Value, + }, + ) + ) # rapid move to safe height - op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.SafeHeight.Value})) + op.commandlist.append( + Path.Command( + "G0", + { + "X": helixStart[0], + "Y": helixStart[1], + "Z": obj.SafeHeight.Value, + }, + ) + ) # move to start depth - op.commandlist.append(Path.Command("G1", {"X": helixStart[0], "Y": helixStart[1], "Z": passStartDepth, "F": op.vertFeed})) + op.commandlist.append( + Path.Command( + "G1", + { + "X": helixStart[0], + "Y": helixStart[1], + "Z": passStartDepth, + "F": op.vertFeed, + }, + ) + ) x = region["HelixCenterPoint"][0] + r y = region["HelixCenterPoint"][1] curDep = passStartDepth while curDep > (passEndDepth + depthPerOneCircle): - op.commandlist.append(Path.Command("G2", {"X": x - (2*r), "Y": y, "Z": curDep - (depthPerOneCircle/2), "I": -r, "F": op.vertFeed})) - op.commandlist.append(Path.Command("G2", {"X": x, "Y": y, "Z": curDep - depthPerOneCircle, "I": r, "F": op.vertFeed})) + op.commandlist.append( + Path.Command( + "G2", + { + "X": x - (2 * r), + "Y": y, + "Z": curDep - (depthPerOneCircle / 2), + "I": -r, + "F": op.vertFeed, + }, + ) + ) + op.commandlist.append( + Path.Command( + "G2", + { + "X": x, + "Y": y, + "Z": curDep - depthPerOneCircle, + "I": r, + "F": op.vertFeed, + }, + ) + ) curDep = curDep - depthPerOneCircle lastStep = curDep - passEndDepth - if lastStep > (depthPerOneCircle/2): - op.commandlist.append(Path.Command("G2", {"X": x - (2*r), "Y": y, "Z": curDep - (lastStep/2), "I": -r, "F": op.vertFeed})) - op.commandlist.append(Path.Command("G2", {"X": x, "Y": y, "Z": passEndDepth, "I": r, "F": op.vertFeed})) + if lastStep > (depthPerOneCircle / 2): + op.commandlist.append( + Path.Command( + "G2", + { + "X": x - (2 * r), + "Y": y, + "Z": curDep - (lastStep / 2), + "I": -r, + "F": op.vertFeed, + }, + ) + ) + op.commandlist.append( + Path.Command( + "G2", + { + "X": x, + "Y": y, + "Z": passEndDepth, + "I": r, + "F": op.vertFeed, + }, + ) + ) else: - op.commandlist.append(Path.Command("G2", {"X": x - (2*r), "Y": y, "Z": passEndDepth, "I": -r, "F": op.vertFeed})) - op.commandlist.append(Path.Command("G1", {"X": x, "Y": y, "Z": passEndDepth, "F": op.vertFeed})) + op.commandlist.append( + Path.Command( + "G2", + { + "X": x - (2 * r), + "Y": y, + "Z": passEndDepth, + "I": -r, + "F": op.vertFeed, + }, + ) + ) + op.commandlist.append( + Path.Command( + "G1", + {"X": x, "Y": y, "Z": passEndDepth, "F": op.vertFeed}, + ) + ) # one more circle at target depth to make sure center is cleared - op.commandlist.append(Path.Command("G2", {"X": x - (2*r), "Y": y, "Z": passEndDepth, "I": -r, "F": op.horizFeed})) - op.commandlist.append(Path.Command("G2", {"X": x, "Y": y, "Z": passEndDepth, "I": r, "F": op.horizFeed})) + op.commandlist.append( + Path.Command( + "G2", + { + "X": x - (2 * r), + "Y": y, + "Z": passEndDepth, + "I": -r, + "F": op.horizFeed, + }, + ) + ) + op.commandlist.append( + Path.Command( + "G2", + { + "X": x, + "Y": y, + "Z": passEndDepth, + "I": r, + "F": op.horizFeed, + }, + ) + ) # lx = x # ly = y else: # no helix entry # rapid move to clearance height - op.commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value})) - op.commandlist.append(Path.Command("G0", {"X": region["StartPoint"][0], "Y": region["StartPoint"][1], "Z": obj.ClearanceHeight.Value})) + op.commandlist.append( + Path.Command("G0", {"Z": obj.ClearanceHeight.Value}) + ) + op.commandlist.append( + Path.Command( + "G0", + { + "X": region["StartPoint"][0], + "Y": region["StartPoint"][1], + "Z": obj.ClearanceHeight.Value, + }, + ) + ) # straight plunge to target depth - op.commandlist.append(Path.Command("G1", {"X": region["StartPoint"][0], "Y": region["StartPoint"][1], "Z": passEndDepth, "F": op.vertFeed})) + op.commandlist.append( + Path.Command( + "G1", + { + "X": region["StartPoint"][0], + "Y": region["StartPoint"][1], + "Z": passEndDepth, + "F": op.vertFeed, + }, + ) + ) lz = passEndDepth z = obj.ClearanceHeight.Value @@ -349,9 +596,13 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): if motionType == area.AdaptiveMotionType.Cutting: z = passEndDepth if z != lz: - op.commandlist.append(Path.Command("G1", {"Z": z, "F": op.vertFeed})) + op.commandlist.append( + Path.Command("G1", {"Z": z, "F": op.vertFeed}) + ) - op.commandlist.append(Path.Command("G1", {"X": x, "Y": y, "F": op.horizFeed})) + op.commandlist.append( + Path.Command("G1", {"X": x, "Y": y, "F": op.horizFeed}) + ) elif motionType == area.AdaptiveMotionType.LinkClear: z = passEndDepth + stepUp @@ -411,7 +662,7 @@ def Execute(op, obj): obj.Path = Path.Path("(Calculating...)") if FreeCAD.GuiUp: - #store old visibility state + # store old visibility state job = op.getJob(obj) oldObjVisibility = obj.ViewObject.Visibility oldJobVisibility = job.ViewObject.Visibility @@ -469,7 +720,7 @@ def Execute(op, obj): opType = area.AdaptiveOperationType.ProfilingInside keepToolDownRatio = 3.0 - if hasattr(obj, 'KeepToolDownRatio'): + if hasattr(obj, "KeepToolDownRatio"): keepToolDownRatio = float(obj.KeepToolDownRatio) # put here all properties that influence calculation of adaptive base paths, @@ -486,7 +737,7 @@ def Execute(op, obj): "forceInsideOut": obj.ForceInsideOut, "finishingProfile": obj.FinishingProfile, "keepToolDownRatio": keepToolDownRatio, - "stockToLeave": float(obj.StockToLeave) + "stockToLeave": float(obj.StockToLeave), } inputStateChanged = False @@ -502,12 +753,16 @@ def Execute(op, obj): # progress callback fn, if return true it will stop processing def progressFn(tpaths): if FreeCAD.GuiUp: - for path in tpaths: #path[0] contains the MotionType, #path[1] contains list of points + for ( + path + ) in ( + tpaths + ): # path[0] contains the MotionType, #path[1] contains list of points if path[0] == area.AdaptiveMotionType.Cutting: - sceneDrawPath(path[1],(0,0,1)) + sceneDrawPath(path[1], (0, 0, 1)) else: - sceneDrawPath(path[1],(1,0,1)) + sceneDrawPath(path[1], (1, 0, 1)) FreeCADGui.updateGui() @@ -533,22 +788,27 @@ def Execute(op, obj): # need to convert results to python object to be JSON serializable adaptiveResults = [] for result in results: - adaptiveResults.append({ - "HelixCenterPoint": result.HelixCenterPoint, - "StartPoint": result.StartPoint, - "AdaptivePaths": result.AdaptivePaths, - "ReturnMotionType": result.ReturnMotionType}) + adaptiveResults.append( + { + "HelixCenterPoint": result.HelixCenterPoint, + "StartPoint": result.StartPoint, + "AdaptivePaths": result.AdaptivePaths, + "ReturnMotionType": result.ReturnMotionType, + } + ) # GENERATE GenerateGCode(op, obj, adaptiveResults, helixDiameter) if not obj.StopProcessing: - PathLog.info("*** Done. Elapsed time: %f sec\n\n" % (time.time()-start)) + PathLog.info("*** Done. Elapsed time: %f sec\n\n" % (time.time() - start)) obj.AdaptiveOutputState = adaptiveResults obj.AdaptiveInputState = inputStateObject else: - PathLog.info("*** Processing cancelled (after: %f sec).\n\n" % (time.time()-start)) + PathLog.info( + "*** Processing cancelled (after: %f sec).\n\n" % (time.time() - start) + ) finally: if FreeCAD.GuiUp: @@ -558,12 +818,12 @@ def Execute(op, obj): def _get_working_edges(op, obj): - '''_get_working_edges(op, obj)... + """_get_working_edges(op, obj)... Compile all working edges from the Base Geometry selection (obj.Base) for the current operation. Additional modifications to selected region(face), such as extensions, should be placed within this function. - ''' + """ all_regions = list() edge_list = list() avoidFeatures = list() @@ -603,7 +863,7 @@ def _get_working_edges(op, obj): edge_list.append([discretize(e)]) # Apply regular Extensions - op.exts = [] # pylint: disable=attribute-defined-outside-init + op.exts = [] # pylint: disable=attribute-defined-outside-init for ext in extensions: if not ext.avoid: wire = ext.getWire() @@ -626,55 +886,250 @@ def _get_working_edges(op, obj): class PathAdaptive(PathOp.ObjectOp): def opFeatures(self, obj): - '''opFeatures(obj) ... returns the OR'ed list of features used and supported by the operation. + """opFeatures(obj) ... returns the OR'ed list of features used and supported by the operation. The default implementation returns "FeatureTool | FeatureDepths | FeatureHeights | FeatureStartPoint" - Should be overwritten by subclasses.''' - return PathOp.FeatureTool | PathOp.FeatureBaseEdges | PathOp.FeatureDepths \ - | PathOp.FeatureFinishDepth | PathOp.FeatureStepDown | PathOp.FeatureHeights \ - | PathOp.FeatureBaseGeometry | PathOp.FeatureCoolant | PathOp.FeatureLocations + Should be overwritten by subclasses.""" + return ( + PathOp.FeatureTool + | PathOp.FeatureBaseEdges + | PathOp.FeatureDepths + | PathOp.FeatureFinishDepth + | PathOp.FeatureStepDown + | PathOp.FeatureHeights + | PathOp.FeatureBaseGeometry + | PathOp.FeatureCoolant + | PathOp.FeatureLocations + ) + + @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 = { + "Side": [ + (translate("Path_Adaptive", "Outside"), "Outside"), + (translate("Path_Adaptive", "Inside"), "Inside"), + ], # this is the direction that the profile runs + "OperationType": [ + (translate("Path_Adaptive", "Clearing"), "Clearing"), + (translate("Path_Adaptive", "Profiling"), "Profiling"), + ], # side of profile that cutter is on in relation to direction of profile + } + + 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 initOperation(self, obj): - '''initOperation(obj) ... implement to create additional properties. - Should be overwritten by subclasses.''' - obj.addProperty("App::PropertyEnumeration", "Side", "Adaptive", "Side of selected faces that tool should cut") - obj.Side = ['Outside', 'Inside'] # side of profile that cutter is on in relation to direction of profile + """initOperation(obj) ... implement to create additional properties. + Should be overwritten by subclasses.""" + obj.addProperty( + "App::PropertyEnumeration", + "Side", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Side of selected faces that tool should cut", + ), + ) + # obj.Side = [ + # "Outside", + # "Inside", + # ] # side of profile that cutter is on in relation to direction of profile - obj.addProperty("App::PropertyEnumeration", "OperationType", "Adaptive", "Type of adaptive operation") - obj.OperationType = ['Clearing', 'Profiling'] # side of profile that cutter is on in relation to direction of profile + obj.addProperty( + "App::PropertyEnumeration", + "OperationType", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Type of adaptive operation", + ), + ) + # obj.OperationType = [ + # "Clearing", + # "Profiling", + # ] # side of profile that cutter is on in relation to direction of profile - obj.addProperty("App::PropertyFloat", "Tolerance", "Adaptive", "Influences accuracy and performance") - obj.addProperty("App::PropertyPercent", "StepOver", "Adaptive", "Percent of cutter diameter to step over on each pass") - obj.addProperty("App::PropertyDistance", "LiftDistance", "Adaptive", "Lift distance for rapid moves") - obj.addProperty("App::PropertyDistance", "KeepToolDownRatio", "Adaptive", "Max length of keep tool down path compared to direct distance between points") - obj.addProperty("App::PropertyDistance", "StockToLeave", "Adaptive", "How much stock to leave (i.e. for finishing operation)") - # obj.addProperty("App::PropertyBool", "ProcessHoles", "Adaptive","Process holes as well as the face outline") + obj.addProperty( + "App::PropertyFloat", + "Tolerance", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Influences accuracy and performance", + ), + ) + obj.addProperty( + "App::PropertyPercent", + "StepOver", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Percent of cutter diameter to step over on each pass", + ), + ) + obj.addProperty( + "App::PropertyDistance", + "LiftDistance", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Lift distance for rapid moves", + ), + ) + obj.addProperty( + "App::PropertyDistance", + "KeepToolDownRatio", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Max length of keep tool down path compared to direct distance between points", + ), + ) + obj.addProperty( + "App::PropertyDistance", + "StockToLeave", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "How much stock to leave (i.e. for finishing operation)", + ), + ) + obj.addProperty( + "App::PropertyBool", + "ForceInsideOut", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Force plunging into material inside and clearing towards the edges", + ), + ) + obj.addProperty( + "App::PropertyBool", + "FinishingProfile", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "To take a finishing profile path at the end", + ), + ) + obj.addProperty( + "App::PropertyBool", + "Stopped", + "Adaptive", + QT_TRANSLATE_NOOP("App::Property", "Stop processing"), + ) + obj.setEditorMode("Stopped", 2) # hide this property - obj.addProperty("App::PropertyBool", "ForceInsideOut", "Adaptive", "Force plunging into material inside and clearing towards the edges") - obj.addProperty("App::PropertyBool", "FinishingProfile", "Adaptive", "To take a finishing profile path at the end") - obj.addProperty("App::PropertyBool", "Stopped", - "Adaptive", "Stop processing") - obj.setEditorMode('Stopped', 2) # hide this property + obj.addProperty( + "App::PropertyBool", + "StopProcessing", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Stop processing", + ), + ) + obj.setEditorMode("StopProcessing", 2) # hide this property - obj.addProperty("App::PropertyBool", "StopProcessing", - "Adaptive", "Stop processing") - obj.setEditorMode('StopProcessing', 2) # hide this property + obj.addProperty( + "App::PropertyBool", + "UseHelixArcs", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Use Arcs (G2) for helix ramp", + ), + ) - obj.addProperty("App::PropertyBool", "UseHelixArcs", "Adaptive", "Use Arcs (G2) for helix ramp") + obj.addProperty( + "App::PropertyPythonObject", + "AdaptiveInputState", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Internal input state", + ), + ) + obj.addProperty( + "App::PropertyPythonObject", + "AdaptiveOutputState", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Internal output state", + ), + ) + obj.setEditorMode("AdaptiveInputState", 2) # hide this property + obj.setEditorMode("AdaptiveOutputState", 2) # hide this property + obj.addProperty( + "App::PropertyAngle", + "HelixAngle", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Helix ramp entry angle (degrees)", + ), + ) + obj.addProperty( + "App::PropertyAngle", + "HelixConeAngle", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Helix cone angle (degrees)", + ), + ) + obj.addProperty( + "App::PropertyLength", + "HelixDiameterLimit", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Limit helix entry diameter, if limit larger than tool diameter or 0, tool diameter is used", + ), + ) - obj.addProperty("App::PropertyPythonObject", "AdaptiveInputState", - "Adaptive", "Internal input state") - obj.addProperty("App::PropertyPythonObject", "AdaptiveOutputState", - "Adaptive", "Internal output state") - obj.setEditorMode('AdaptiveInputState', 2) # hide this property - obj.setEditorMode('AdaptiveOutputState', 2) # hide this property - obj.addProperty("App::PropertyAngle", "HelixAngle", "Adaptive", "Helix ramp entry angle (degrees)") - obj.addProperty("App::PropertyAngle", "HelixConeAngle", "Adaptive", "Helix cone angle (degrees)") - obj.addProperty("App::PropertyLength", "HelixDiameterLimit", "Adaptive", "Limit helix entry diameter, if limit larger than tool diameter or 0, tool diameter is used") + obj.addProperty( + "App::PropertyBool", + "UseOutline", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Uses the outline of the base geometry.", + ), + ) - obj.addProperty("App::PropertyBool", "UseOutline", "Adaptive", "Uses the outline of the base geometry.") + obj.addProperty( + "Part::PropertyPartShape", + "removalshape", + "Path", + QT_TRANSLATE_NOOP("App::Property", ""), + ) - obj.addProperty("Part::PropertyPartShape", "removalshape", "Path", "") - obj.setEditorMode('removalshape', 2) # hide + for n in self.propertyEnumerations(): + setattr(obj, n[0], n[1]) + + obj.setEditorMode("removalshape", 2) # hide FeatureExtensions.initialize_properties(obj) @@ -701,43 +1156,66 @@ class PathAdaptive(PathOp.ObjectOp): FeatureExtensions.set_default_property_values(obj, job) def opExecute(self, obj): - '''opExecute(obj) ... called whenever the receiver needs to be recalculated. + """opExecute(obj) ... called whenever the receiver needs to be recalculated. See documentation of execute() for a list of base functionality provided. - Should be overwritten by subclasses.''' + Should be overwritten by subclasses.""" self.pathArray = _get_working_edges(self, obj) Execute(self, obj) def opOnDocumentRestored(self, obj): - if not hasattr(obj, 'HelixConeAngle'): - obj.addProperty("App::PropertyAngle", "HelixConeAngle", "Adaptive", "Helix cone angle (degrees)") + if not hasattr(obj, "HelixConeAngle"): + obj.addProperty( + "App::PropertyAngle", + "HelixConeAngle", + "Adaptive", + "Helix cone angle (degrees)", + ) if not hasattr(obj, "UseOutline"): - obj.addProperty("App::PropertyBool", - "UseOutline", - "Adaptive", - "Uses the outline of the base geometry.") + obj.addProperty( + "App::PropertyBool", + "UseOutline", + "Adaptive", + "Uses the outline of the base geometry.", + ) if not hasattr(obj, "removalshape"): obj.addProperty("Part::PropertyPartShape", "removalshape", "Path", "") - obj.setEditorMode('removalshape', 2) # hide + obj.setEditorMode("removalshape", 2) # hide FeatureExtensions.initialize_properties(obj) + + # Eclass def SetupProperties(): - setup = ["Side", "OperationType", "Tolerance", "StepOver", - "LiftDistance", "KeepToolDownRatio", "StockToLeave", - "ForceInsideOut", "FinishingProfile", "Stopped", - "StopProcessing", "UseHelixArcs", "AdaptiveInputState", - "AdaptiveOutputState", "HelixAngle", "HelixConeAngle", - "HelixDiameterLimit", "UseOutline"] + setup = [ + "Side", + "OperationType", + "Tolerance", + "StepOver", + "LiftDistance", + "KeepToolDownRatio", + "StockToLeave", + "ForceInsideOut", + "FinishingProfile", + "Stopped", + "StopProcessing", + "UseHelixArcs", + "AdaptiveInputState", + "AdaptiveOutputState", + "HelixAngle", + "HelixConeAngle", + "HelixDiameterLimit", + "UseOutline", + ] return setup def Create(name, obj=None, parentJob=None): - '''Create(name) ... Creates and returns a Adaptive operation.''' + """Create(name) ... Creates and returns a Adaptive operation.""" if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) obj.Proxy = PathAdaptive(obj, name, parentJob) diff --git a/src/Mod/Path/PathScripts/PathAdaptiveGui.py b/src/Mod/Path/PathScripts/PathAdaptiveGui.py index daa2335926..113fc1d91d 100644 --- a/src/Mod/Path/PathScripts/PathAdaptiveGui.py +++ b/src/Mod/Path/PathScripts/PathAdaptiveGui.py @@ -22,142 +22,41 @@ # *************************************************************************** import PathScripts.PathOpGui as PathOpGui -from PySide import QtCore, QtGui +from PySide import QtCore import PathScripts.PathAdaptive as PathAdaptive import PathScripts.PathFeatureExtensionsGui as PathFeatureExtensionsGui +import FreeCADGui class TaskPanelOpPage(PathOpGui.TaskPanelPage): - def initPage(self, obj): - self.setTitle("Adaptive path operation") - def getForm(self): - form = QtGui.QWidget() - layout = QtGui.QVBoxLayout() - formLayout = QtGui.QFormLayout() + """getForm() ... return UI""" - # tool controller - form.ToolController = QtGui.QComboBox() - formLayout.addRow(QtGui.QLabel("Tool Controller"), form.ToolController) + form = FreeCADGui.PySideUic.loadUi(":/panels/PageOpAdaptiveEdit.ui") + comboToPropertyMap = [("Side", "Side"), ("OperationType", "OperationType")] - # Coolant controller - form.coolantController = QtGui.QComboBox() - formLayout.addRow(QtGui.QLabel("Coolant Mode"), form.coolantController) + enumTups = PathAdaptive.PathAdaptive.propertyEnumerations(dataType="raw") - # cut region - form.Side = QtGui.QComboBox() - form.Side.addItem("Inside") - form.Side.addItem("Outside") - form.Side.setToolTip("Cut inside or outside of the selected shapes") - formLayout.addRow(QtGui.QLabel("Cut Region"), form.Side) - - # operation type - form.OperationType = QtGui.QComboBox() - form.OperationType.addItem("Clearing") - form.OperationType.addItem("Profiling") - form.OperationType.setToolTip("Type of adaptive operation") - formLayout.addRow(QtGui.QLabel("Operation Type"), form.OperationType) - - # step over - form.StepOver = QtGui.QSpinBox() - form.StepOver.setMinimum(15) - form.StepOver.setMaximum(75) - form.StepOver.setSingleStep(1) - form.StepOver.setValue(25) - form.StepOver.setToolTip("Optimal value for tool stepover") - formLayout.addRow(QtGui.QLabel("Step Over Percent"), form.StepOver) - - # tolerance - form.Tolerance = QtGui.QSlider(QtCore.Qt.Horizontal) - form.Tolerance.setMinimum(5) - form.Tolerance.setMaximum(15) - form.Tolerance.setTickInterval(1) - form.Tolerance.setValue(10) - form.Tolerance.setTickPosition(QtGui.QSlider.TicksBelow) - form.Tolerance.setToolTip("Influences calculation performance vs stability and accuracy.") - formLayout.addRow(QtGui.QLabel("Accuracy vs Performance"), form.Tolerance) - - # helix angle - form.HelixAngle = QtGui.QDoubleSpinBox() - form.HelixAngle.setMinimum(1) - form.HelixAngle.setMaximum(89) - form.HelixAngle.setSingleStep(1) - form.HelixAngle.setValue(5) - form.HelixAngle.setToolTip("Angle of the helix ramp entry") - formLayout.addRow(QtGui.QLabel("Helix Ramp Angle"), form.HelixAngle) - - # helix cone angle - form.HelixConeAngle = QtGui.QDoubleSpinBox() - form.HelixConeAngle.setMinimum(0) - form.HelixConeAngle.setMaximum(6) - form.HelixConeAngle.setSingleStep(1) - form.HelixConeAngle.setValue(0) - form.HelixConeAngle.setToolTip("Angle of the helix entry cone") - formLayout.addRow(QtGui.QLabel("Helix Cone Angle"), form.HelixConeAngle) - - # helix diam. limit - form.HelixDiameterLimit = QtGui.QDoubleSpinBox() - form.HelixDiameterLimit.setMinimum(0.0) - form.HelixDiameterLimit.setMaximum(90) - form.HelixDiameterLimit.setSingleStep(0.1) - form.HelixDiameterLimit.setValue(0) - form.HelixDiameterLimit.setToolTip("If >0 it limits the helix ramp diameter\notherwise the 75 percent of tool diameter is used as helix diameter") - formLayout.addRow(QtGui.QLabel("Helix Max Diameter"), form.HelixDiameterLimit) - - # lift distance - form.LiftDistance = QtGui.QDoubleSpinBox() - form.LiftDistance.setMinimum(0.0) - form.LiftDistance.setMaximum(1000) - form.LiftDistance.setSingleStep(0.1) - form.LiftDistance.setValue(1.0) - form.LiftDistance.setToolTip("How much to lift the tool up during the rapid linking moves over cleared regions.\nIf linking path is not clear tool is raised to clearence height.") - formLayout.addRow(QtGui.QLabel("Lift Distance"), form.LiftDistance) - - # KeepToolDownRatio - form.KeepToolDownRatio = QtGui.QDoubleSpinBox() - form.KeepToolDownRatio.setMinimum(1.0) - form.KeepToolDownRatio.setMaximum(10) - form.KeepToolDownRatio.setSingleStep(1) - form.KeepToolDownRatio.setValue(3.0) - form.KeepToolDownRatio.setToolTip("Max length of keep-tool-down linking path compared to direct distance between points.\nIf exceeded link will be done by raising the tool to clearence height.") - formLayout.addRow(QtGui.QLabel("Keep Tool Down Ratio"), form.KeepToolDownRatio) - - # stock to leave - form.StockToLeave = QtGui.QDoubleSpinBox() - form.StockToLeave.setMinimum(0.0) - form.StockToLeave.setMaximum(1000) - form.StockToLeave.setSingleStep(0.1) - form.StockToLeave.setValue(0) - form.StockToLeave.setToolTip("How much material to leave (i.e. for finishing operation)") - formLayout.addRow(QtGui.QLabel("Stock to Leave"), form.StockToLeave) - - # Force inside out - form.ForceInsideOut = QtGui.QCheckBox() - form.ForceInsideOut.setChecked(True) - formLayout.addRow(QtGui.QLabel("Force Clearing Inside-Out"), form.ForceInsideOut) - - # Finishing profile - form.FinishingProfile = QtGui.QCheckBox() - form.FinishingProfile.setChecked(True) - formLayout.addRow(QtGui.QLabel("Finishing Profile"), form.FinishingProfile) - - # Use outline checkbox - form.useOutline = QtGui.QCheckBox() - form.useOutline.setChecked(False) - formLayout.addRow(QtGui.QLabel("Use outline"), form.useOutline) - - layout.addLayout(formLayout) - - # stop button - form.StopButton = QtGui.QPushButton("Stop") - form.StopButton.setCheckable(True) - layout.addWidget(form.StopButton) - - form.setLayout(layout) + 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 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.button.clicked) signals.append(self.form.Side.currentIndexChanged) @@ -189,10 +88,10 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): self.form.HelixConeAngle.setValue(obj.HelixConeAngle) self.form.HelixDiameterLimit.setValue(obj.HelixDiameterLimit) self.form.LiftDistance.setValue(obj.LiftDistance) - if hasattr(obj, 'KeepToolDownRatio'): + if hasattr(obj, "KeepToolDownRatio"): self.form.KeepToolDownRatio.setValue(obj.KeepToolDownRatio) - if hasattr(obj, 'StockToLeave'): + if hasattr(obj, "StockToLeave"): self.form.StockToLeave.setValue(obj.StockToLeave) # self.form.ProcessHoles.setChecked(obj.ProcessHoles) @@ -202,17 +101,17 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): self.setupToolController(obj, self.form.ToolController) self.setupCoolant(obj, self.form.coolantController) self.form.StopButton.setChecked(obj.Stopped) - obj.setEditorMode('AdaptiveInputState', 2) # hide this property - obj.setEditorMode('AdaptiveOutputState', 2) # hide this property - obj.setEditorMode('StopProcessing', 2) # hide this property - obj.setEditorMode('Stopped', 2) # hide this property + obj.setEditorMode("AdaptiveInputState", 2) # hide this property + obj.setEditorMode("AdaptiveOutputState", 2) # hide this property + obj.setEditorMode("StopProcessing", 2) # hide this property + obj.setEditorMode("Stopped", 2) # hide this property def getFields(self, obj): - if obj.Side != str(self.form.Side.currentText()): - obj.Side = str(self.form.Side.currentText()) + if obj.Side != str(self.form.Side.currentData()): + obj.Side = str(self.form.Side.currentData()) - if obj.OperationType != str(self.form.OperationType.currentText()): - obj.OperationType = str(self.form.OperationType.currentText()) + if obj.OperationType != str(self.form.OperationType.currentData()): + obj.OperationType = str(self.form.OperationType.currentData()) obj.StepOver = self.form.StepOver.value() obj.Tolerance = 1.0 * self.form.Tolerance.value() / 100.0 @@ -221,37 +120,41 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): obj.HelixDiameterLimit = self.form.HelixDiameterLimit.value() obj.LiftDistance = self.form.LiftDistance.value() - if hasattr(obj, 'KeepToolDownRatio'): + if hasattr(obj, "KeepToolDownRatio"): obj.KeepToolDownRatio = self.form.KeepToolDownRatio.value() - if hasattr(obj, 'StockToLeave'): + if hasattr(obj, "StockToLeave"): obj.StockToLeave = self.form.StockToLeave.value() obj.ForceInsideOut = self.form.ForceInsideOut.isChecked() obj.FinishingProfile = self.form.FinishingProfile.isChecked() obj.UseOutline = self.form.useOutline.isChecked() obj.Stopped = self.form.StopButton.isChecked() - if(obj.Stopped): + if obj.Stopped: self.form.StopButton.setChecked(False) # reset the button obj.StopProcessing = True self.updateToolController(obj, self.form.ToolController) self.updateCoolant(obj, self.form.coolantController) - obj.setEditorMode('AdaptiveInputState', 2) # hide this property - obj.setEditorMode('AdaptiveOutputState', 2) # hide this property - obj.setEditorMode('StopProcessing', 2) # hide this property - obj.setEditorMode('Stopped', 2) # hide this property + obj.setEditorMode("AdaptiveInputState", 2) # hide this property + obj.setEditorMode("AdaptiveOutputState", 2) # hide this property + obj.setEditorMode("StopProcessing", 2) # hide this property + obj.setEditorMode("Stopped", 2) # hide this property def taskPanelBaseLocationPage(self, obj, features): - if not hasattr(self, 'extensionsPanel'): - self.extensionsPanel = PathFeatureExtensionsGui.TaskPanelExtensionPage(obj, features) # pylint: disable=attribute-defined-outside-init + if not hasattr(self, "extensionsPanel"): + self.extensionsPanel = PathFeatureExtensionsGui.TaskPanelExtensionPage( + obj, features + ) # pylint: disable=attribute-defined-outside-init return self.extensionsPanel -Command = PathOpGui.SetupOperation('Adaptive', - PathAdaptive.Create, - TaskPanelOpPage, - 'Path_Adaptive', - QtCore.QT_TRANSLATE_NOOP("Path_Adaptive", "Adaptive"), - QtCore.QT_TRANSLATE_NOOP("Path_Adaptive", "Adaptive clearing and profiling"), - PathAdaptive.SetupProperties) +Command = PathOpGui.SetupOperation( + "Adaptive", + PathAdaptive.Create, + TaskPanelOpPage, + "Path_Adaptive", + QtCore.QT_TRANSLATE_NOOP("Path_Adaptive", "Adaptive"), + QtCore.QT_TRANSLATE_NOOP("Path_Adaptive", "Adaptive clearing and profiling"), + PathAdaptive.SetupProperties, +) diff --git a/src/Mod/Path/PathScripts/PathPreferencesAdvanced.py b/src/Mod/Path/PathScripts/PathPreferencesAdvanced.py index 5b9151587b..4a9b3903dc 100644 --- a/src/Mod/Path/PathScripts/PathPreferencesAdvanced.py +++ b/src/Mod/Path/PathScripts/PathPreferencesAdvanced.py @@ -24,37 +24,46 @@ import FreeCADGui import PathScripts.PathPreferences as PathPreferences import PySide -# Qt translation handling -def translate(context, text, disambig=None): - return PySide.QtCore.QCoreApplication.translate(context, text, disambig) class AdvancedPreferencesPage: def __init__(self, parent=None): - self.form = FreeCADGui.PySideUic.loadUi(':preferences/Advanced.ui') + self.form = FreeCADGui.PySideUic.loadUi(":preferences/Advanced.ui") self.form.WarningSuppressAllSpeeds.stateChanged.connect(self.updateSelection) self.form.EnableAdvancedOCLFeatures.stateChanged.connect(self.updateSelection) def saveSettings(self): PathPreferences.setPreferencesAdvanced( - self.form.EnableAdvancedOCLFeatures.isChecked(), - self.form.WarningSuppressAllSpeeds.isChecked(), - self.form.WarningSuppressRapidSpeeds.isChecked(), - self.form.WarningSuppressSelectionMode.isChecked(), - self.form.WarningSuppressOpenCamLib.isChecked()) + self.form.EnableAdvancedOCLFeatures.isChecked(), + self.form.WarningSuppressAllSpeeds.isChecked(), + self.form.WarningSuppressRapidSpeeds.isChecked(), + self.form.WarningSuppressSelectionMode.isChecked(), + self.form.WarningSuppressOpenCamLib.isChecked(), + ) def loadSettings(self): - self.form.WarningSuppressAllSpeeds.setChecked(PathPreferences.suppressAllSpeedsWarning()) - self.form.WarningSuppressRapidSpeeds.setChecked(PathPreferences.suppressRapidSpeedsWarning(False)) - self.form.WarningSuppressSelectionMode.setChecked(PathPreferences.suppressSelectionModeWarning()) - self.form.EnableAdvancedOCLFeatures.setChecked(PathPreferences.advancedOCLFeaturesEnabled()) - self.form.WarningSuppressOpenCamLib.setChecked(PathPreferences.suppressOpenCamLibWarning()) + self.form.WarningSuppressAllSpeeds.setChecked( + PathPreferences.suppressAllSpeedsWarning() + ) + self.form.WarningSuppressRapidSpeeds.setChecked( + PathPreferences.suppressRapidSpeedsWarning(False) + ) + self.form.WarningSuppressSelectionMode.setChecked( + PathPreferences.suppressSelectionModeWarning() + ) + self.form.EnableAdvancedOCLFeatures.setChecked( + PathPreferences.advancedOCLFeaturesEnabled() + ) + self.form.WarningSuppressOpenCamLib.setChecked( + PathPreferences.suppressOpenCamLibWarning() + ) self.updateSelection() def updateSelection(self, state=None): - self.form.WarningSuppressOpenCamLib.setEnabled(self.form.EnableAdvancedOCLFeatures.isChecked()) + self.form.WarningSuppressOpenCamLib.setEnabled( + self.form.EnableAdvancedOCLFeatures.isChecked() + ) if self.form.WarningSuppressAllSpeeds.isChecked(): self.form.WarningSuppressRapidSpeeds.setChecked(True) self.form.WarningSuppressRapidSpeeds.setEnabled(False) else: self.form.WarningSuppressRapidSpeeds.setEnabled(True) -