From 7a6a3fb967d743bc5b36f004f15df14da0a63d19 Mon Sep 17 00:00:00 2001 From: Patrick Felixberger Date: Tue, 23 Apr 2019 00:16:25 +0200 Subject: [PATCH 1/3] Cleaned up PathAdaptive script --- src/Mod/Path/PathScripts/PathAdaptive.py | 252 ++++++++++++++--------- 1 file changed, 152 insertions(+), 100 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAdaptive.py b/src/Mod/Path/PathScripts/PathAdaptive.py index 332d38a372..7e13b274dd 100644 --- a/src/Mod/Path/PathScripts/PathAdaptive.py +++ b/src/Mod/Path/PathScripts/PathAdaptive.py @@ -54,6 +54,7 @@ def sceneDrawPath(path, color=(0, 0, 1)): global sceneGraph global scenePathNodes coPoint = coin.SoCoordinate3() + pts = [] for pt in path: pts.append([pt[0], pt[1], topZ]) @@ -72,41 +73,54 @@ def sceneDrawPath(path, color=(0, 0, 1)): def sceneClean(): global scenePathNodes + for n in scenePathNodes: sceneGraph.removeChild(n) + del scenePathNodes[:] -def discretize(edge, flipDirection=False): - pts=edge.discretize(Deflection=0.0001) - if flipDirection: pts.reverse() +def discretize(edge, flipDirection = False): + pts = edge.discretize(Deflection = 0.0001) + if flipDirection: + pts.reverse() + return pts def GenerateGCode(op,obj,adaptiveResults, helixDiameter): - if len(adaptiveResults)==0 or len(adaptiveResults[0]["AdaptivePaths"])==0: - return + if len(adaptiveResults) == 0 or len(adaptiveResults[0]["AdaptivePaths"]) == 0: + return minLiftDistance = op.tool.Diameter - helixRadius=0 + helixRadius = 0 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])) - if r>helixRadius: helixRadius=r + if r > helixRadius: + helixRadius = r stepDown = obj.StepDown.Value passStartDepth=obj.StartDepth.Value - if stepDown<0.1 : stepDown=0.1 + + if stepDown < 0.1 : + stepDown = 0.1 + length = 2*math.pi * helixRadius - if float(obj.HelixAngle)<1: obj.HelixAngle=1 - helixAngleRad = math.pi * float(obj.HelixAngle)/180.0 + + if float(obj.HelixAngle) < 1: + obj.HelixAngle = 1 + + helixAngleRad = math.pi * float(obj.HelixAngle) / 180.0 depthPerOneCircle=length * math.tan(helixAngleRad) - stepUp = obj.LiftDistance.Value - if stepUp<0: - stepUp=0 + + stepUp = obj.LiftDistance.Value + if stepUp < 0: + stepUp = 0 finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0 - if finish_step>stepDown: finish_step = stepDown + if finish_step > stepDown: + finish_step = stepDown depth_params = PathUtils.depth_params( clearance_height=obj.ClearanceHeight.Value, @@ -119,111 +133,137 @@ def GenerateGCode(op,obj,adaptiveResults, helixDiameter): - lx=adaptiveResults[0]["HelixCenterPoint"][0] - ly=adaptiveResults[0]["HelixCenterPoint"][1] - lz=passStartDepth - step=0 + lx = adaptiveResults[0]["HelixCenterPoint"][0] + ly = adaptiveResults[0]["HelixCenterPoint"][1] + lz = passStartDepth + step = 0 + for passEndDepth in depth_params.data: - step=step+1 + step = step + 1 + for region in adaptiveResults: startAngle = math.atan2(region["StartPoint"][1] - region["HelixCenterPoint"][1], region["StartPoint"][0] - region["HelixCenterPoint"][0]) - lx=region["HelixCenterPoint"][0] - ly=region["HelixCenterPoint"][1] + lx = region["HelixCenterPoint"][0] + ly = region["HelixCenterPoint"][1] 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])) + 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])) - #helix ramp - if helixRadius>0.0001: + # helix ramp + if helixRadius > 0.001: r = helixRadius - 0.01 - maxfi = passDepth / depthPerOneCircle * 2 * math.pi + maxfi = passDepth / depthPerOneCircle * 2 * math.pi fi = 0 offsetFi =-maxfi + startAngle-math.pi/16 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)) - #rapid move to start point - 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})) + # rapid move to start point + op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.ClearanceHeight.Value})) - op.commandlist.append(Path.Command("G1", { - "X": helixStart[0], "Y": helixStart[1], "Z": passStartDepth, "F": op.vertFeed})) + # rapid move to safe height + op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.SafeHeight.Value})) - while fi Date: Tue, 23 Apr 2019 20:10:17 +0200 Subject: [PATCH 2/3] Added optional Arcs (G2) for helix ramp --- src/Mod/Path/PathScripts/PathAdaptive.py | 90 +++++++++++++++++------- 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAdaptive.py b/src/Mod/Path/PathScripts/PathAdaptive.py index 7e13b274dd..ddf5900fb4 100644 --- a/src/Mod/Path/PathScripts/PathAdaptive.py +++ b/src/Mod/Path/PathScripts/PathAdaptive.py @@ -111,7 +111,8 @@ def GenerateGCode(op,obj,adaptiveResults, helixDiameter): obj.HelixAngle = 1 helixAngleRad = math.pi * float(obj.HelixAngle) / 180.0 - depthPerOneCircle=length * math.tan(helixAngleRad) + depthPerOneCircle = length * math.tan(helixAngleRad) + #print("Helix circle depth: {}".format(depthPerOneCircle)) stepUp = obj.LiftDistance.Value if stepUp < 0: @@ -156,42 +157,78 @@ def GenerateGCode(op,obj,adaptiveResults, helixDiameter): # helix ramp if helixRadius > 0.001: r = helixRadius - 0.01 + 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)] op.commandlist.append(Path.Command("(Helix to depth: %f)"%passEndDepth)) - # rapid move to start point - op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.ClearanceHeight.Value})) + if obj.UseHelixArcs == False: + # rapid move to start point + 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})) + # rapid move to safe height + 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})) + # move to start depth + op.commandlist.append(Path.Command("G1", {"X": helixStart[0], "Y": helixStart[1], "Z": passStartDepth, "F": op.vertFeed})) - 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})) + 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})) + 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 + while fi < maxfi: + 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})) + lx = x + ly = y + fi = fi + math.pi/16 + else: + helixStart = [region["HelixCenterPoint"][0] + r, region["HelixCenterPoint"][1]] + + # rapid move to start point + 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})) + + # move to start depth + 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.horizFeed})) + op.commandlist.append(Path.Command("G2", { "X": x, "Y": y, "Z": curDep - depthPerOneCircle, "I": r, "F": op.horizFeed})) + 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.horizFeed})) + op.commandlist.append(Path.Command("G2", { "X": x, "Y": y, "Z": passEndDepth, "I": r, "F": op.horizFeed})) + else: + op.commandlist.append(Path.Command("G2", { "X": x - (2*r), "Y": y, "Z": passEndDepth, "I": -r, "F": op.horizFeed})) + 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})) 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 - while fi < maxfi: - 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})) - lx = x - ly = y - fi = fi + math.pi/16 else: # no helix entry # rapid move to clearance height @@ -453,6 +490,8 @@ class PathAdaptive(PathOp.ObjectOp): "Adaptive", "Stop processing") obj.setEditorMode('StopProcessing', 2) # hide this property + obj.addProperty("App::PropertyBool", "UseHelixArcs", "Adaptive","Use Arcs (G2) for helix ramp") + obj.addProperty("App::PropertyPythonObject", "AdaptiveInputState", "Adaptive", "Internal input state") obj.addProperty("App::PropertyPythonObject", "AdaptiveOutputState", @@ -479,6 +518,7 @@ class PathAdaptive(PathOp.ObjectOp): obj.AdaptiveOutputState = "" obj.StockToLeave = 0 obj.KeepToolDownRatio = 3.0 + obj.UseHelixArcs = False def opExecute(self, obj): '''opExecute(obj) ... called whenever the receiver needs to be recalculated. From 438f3d30ca6d9da370ecb1478a3677314659fda3 Mon Sep 17 00:00:00 2001 From: Patrick Felixberger Date: Tue, 23 Apr 2019 20:17:29 +0200 Subject: [PATCH 3/3] Header changes --- src/Mod/Path/PathScripts/PathAdaptive.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAdaptive.py b/src/Mod/Path/PathScripts/PathAdaptive.py index ddf5900fb4..8feb92d8a7 100644 --- a/src/Mod/Path/PathScripts/PathAdaptive.py +++ b/src/Mod/Path/PathScripts/PathAdaptive.py @@ -17,8 +17,12 @@ # * write to the Free Software Foundation, Inc., 59 Temple Place, * # * Suite 330, Boston, MA 02111-1307, USA * # * * -# ***************************************************************************/ - +# *************************************************************************** +# * * +# * Additional modifications and contributions beginning 2019 * +# * by Schildkroet. (https://github.com/Schildkroet) * +# * * +# **************************************************************************/ import PathScripts.PathOp as PathOp