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 >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)
-