integrating dbtayls helix and ramp entry

integrating dbtayls helix and ramp entry and cleanup

fixed a bug with depth calculation and another with proper entry rapid moves
This commit is contained in:
sliptonic 2016-03-03 10:42:59 -06:00 committed by Yorik van Havre
parent 19812468d1
commit 26bef05db2
7 changed files with 595 additions and 448 deletions

View File

@ -107,6 +107,10 @@ class PathWorkbench ( Workbench ):
if len(FreeCADGui.Selection.getSelection()) == 1:
if FreeCADGui.Selection.getSelection()[0].isDerivedFrom("Path::Feature"):
self.appendContextMenu("",["Path_Inspect"])
if "Profile" in FreeCADGui.Selection.getSelection()[0].Name:
self.appendContextMenu("",["Add_Tag"])
self.appendContextMenu("",["Set_StartPoint"])
self.appendContextMenu("",["Set_EndPoint"])
Gui.addWorkbench(PathWorkbench())

View File

@ -11,7 +11,7 @@ tool_radius_for_pocket = None
def cut_curve(curve, need_rapid, p, rapid_safety_space, current_start_depth, final_depth):
prev_p = p
first = True
#comment("cut_curve:14 rss:" + str(rapid_safety_space) + " current start depth :" + str(current_start_depth) + " final depth :" + str(final_depth) + " need rapid: " + str(need_rapid))
for vertex in curve.getVertices():
if need_rapid and first:
# rapid across
@ -99,29 +99,29 @@ def cut_curvelist1(curve_list, rapid_safety_space, current_start_depth, depth, c
rapid(z = clearance_height)
def cut_curvelist2(curve_list, rapid_safety_space, current_start_depth, depth, clearance_height, keep_tool_down_if_poss,start_point):
p = area.Point(0, 0)
start_x,start_y=start_point
first = True
for curve in curve_list:
need_rapid = True
if first == True:
direction = "on";radius = 0.0;offset_extra = 0.0; roll_radius = 0.0;roll_on = 0.0; roll_off = 0.0; rapid_safety_space; step_down = math.fabs(depth);extend_at_start = 0.0;extend_at_end = 0.0
kurve_funcs.make_smaller( curve, start = area.Point(start_x,start_y))
kurve_funcs.profile(curve, direction, radius , offset_extra, roll_radius, roll_on, roll_off, rapid_safety_space , clearance_height, current_start_depth, step_down , depth, extend_at_start, extend_at_end)
else:
s = curve.FirstVertex().p
if keep_tool_down_if_poss == True:
# def cut_curvelist2(curve_list, rapid_safety_space, current_start_depth, depth, clearance_height, keep_tool_down_if_poss,start_point):
# p = area.Point(0, 0)
# start_x,start_y=start_point
# first = True
# for curve in curve_list:
# need_rapid = True
# if first == True:
# direction = "on";radius = 0.0;offset_extra = 0.0; roll_radius = 0.0;roll_on = 0.0; roll_off = 0.0; rapid_safety_space; step_down = math.fabs(depth);extend_at_start = 0.0;extend_at_end = 0.0
# kurve_funcs.make_smaller( curve, start = area.Point(start_x,start_y))
# kurve_funcs.profile(curve, direction, radius , offset_extra, roll_radius, roll_on, roll_off, rapid_safety_space , clearance_height, current_start_depth, step_down , depth, extend_at_start, extend_at_end)
# else:
# s = curve.FirstVertex().p
# if keep_tool_down_if_poss == True:
# see if we can feed across
if feed_possible(p, s):
need_rapid = False
elif s.x == p.x and s.y == p.y:
need_rapid = False
# # see if we can feed across
# if feed_possible(p, s):
# need_rapid = False
# elif s.x == p.x and s.y == p.y:
# need_rapid = False
cut_curve(curve, need_rapid, p, rapid_safety_space, current_start_depth, depth)
first = False #change to True if you want to rapid back to start side before zigging again with unidirectional set
rapid(z = clearance_height)
# cut_curve(curve, need_rapid, p, rapid_safety_space, current_start_depth, depth)
# first = False #change to True if you want to rapid back to start side before zigging again with unidirectional set
# rapid(z = clearance_height)
def recur(arealist, a1, stepover, from_center):
# this makes arealist by recursively offsetting a1 inwards
@ -428,8 +428,9 @@ def pocket(a,tool_radius, extra_offset, stepover, depthparams, from_center, keep
current_start_depth = depth
else:
for depth in depths:
cut_curvelist2(curve_list, depthparams.rapid_safety_space, current_start_depth, depth, depthparams.clearance_height, keep_tool_down_if_poss, start_point)
current_start_depth = depth
print "PathAreaUtils:438 I guess it IS used. Who knew?"
# for depth in depths:
# cut_curvelist2(curve_list, depthparams.rapid_safety_space, current_start_depth, depth, depthparams.clearance_height, keep_tool_down_if_poss, start_point)
# current_start_depth = depth

View File

@ -37,11 +37,6 @@ from nc.nc import *
import PathScripts.nc.iso
def makeAreaVertex(seg):
if seg.ShapeType =='Edge':
if isinstance(seg.Curve,Part.Circle):
@ -54,18 +49,22 @@ def makeAreaVertex(seg):
vertex = area.Point(seg.valueAt(seg.LastParameter)[0],seg.valueAt(seg.LastParameter)[1])
else:
pass
#print "returning vertex: area.Point(" + str(seg.valueAt(seg.LastParameter)[0]) +"," + str(seg.valueAt(seg.LastParameter)[1]) +")"
return vertex
def makeAreaCurve(edges,direction,startpt=None,endpt=None):
curveobj = area.Curve()
cleanededges = PathUtils.cleanedges(edges, 0.01)
cleanededges = Part.__sortEdges__(PathUtils.cleanedges(edges, 0.01))
for e in cleanededges:
print str(e.valueAt(e.FirstParameter)) + "," + str(e.valueAt(e.LastParameter))
edgelist=[]
if len(cleanededges) == 1: #user selected a single edge.
edgelist = cleanededges
else:
edgelist = [] #Multiple edges. Need to sequence the vetexes.
#edgelist = [] #Multiple edges. Need to sequence the vetexes.
#First get the first segment oriented correctly.
#We first compare the last parameter of the first segment to see if it matches either end of the second segment. If not, it must need flipping.
@ -84,7 +83,7 @@ def makeAreaCurve(edges,direction,startpt=None,endpt=None):
else:
nextedge = PathUtils.reverseEdge(edge)
edgelist.append(nextedge)
#print (str(area.Point(edgelist[0].Vertexes[0].X) + ", " + str(edgelist[0].Vertexes[0].Y)))
#print "makeareacurve 87: " + "area.Point(" + str(edgelist[0].Vertexes[0].X) + ", " + str(edgelist[0].Vertexes[0].Y)+")"
curveobj.append(area.Point(edgelist[0].Vertexes[0].X,edgelist[0].Vertexes[0].Y))
# seglist =[]
# if direction=='CW':

View File

@ -42,69 +42,60 @@ except AttributeError:
def translate(context, text, disambig=None):
return QtGui.QApplication.translate(context, text, disambig)
def frange(start, stop, step, finish):
x = []
curdepth = start
if step == 0:
return x
# do the base cuts until finishing round
while curdepth >= stop + step + finish:
curdepth = curdepth - step
if curdepth <= stop + finish:
curdepth = stop + finish
x.append(curdepth)
# we might have to do a last pass or else finish round might be too far away
if curdepth - stop > finish:
x.append(stop + finish)
# do the the finishing round
if curdepth >= stop:
curdepth = stop
x.append(curdepth)
# Why this?
# if start >= stop:
# start = stop
# x.append (start)
return x
class ObjectPocket:
def __init__(self,obj):
obj.addProperty("App::PropertyLinkSub","Base","Path","The base geometry of this object")
obj.addProperty("App::PropertyIntegerConstraint","ToolNumber","Tool","The tool number in use")
obj.addProperty("App::PropertyLinkSub","Base","Path",translate("PathProject","The base geometry of this object"))
obj.addProperty("App::PropertyBool","Active","Path",translate("PathProject","Make False, to prevent operation from generating code"))
obj.addProperty("App::PropertyString","Comment","Path",translate("PathProject","An optional comment for this profile"))
obj.addProperty("App::PropertyEnumeration", "Algorithm", "Algorithm",translate("PathProject", "The library to use to generate the path"))
obj.Algorithm = ['OCC Native','libarea']
#Tool Properties
obj.addProperty("App::PropertyIntegerConstraint","ToolNumber","Tool",translate("PathProfile","The tool number in use"))
obj.ToolNumber = (0, 0, 1000, 0)
obj.setEditorMode('ToolNumber',1) #make this read only
#Depth Properties
obj.addProperty("App::PropertyFloat", "ClearanceHeight", "Depth", translate("PathProject","The height needed to clear clamps and obstructions"))
obj.addProperty("App::PropertyFloat", "SafeHeight", "Depth", translate("PathProject","Rapid Safety Height between locations."))
obj.addProperty("App::PropertyFloatConstraint", "StepDown", "Depth", translate("PathProject","Incremental Step Down of Tool"))
obj.StepDown = (0.0, 0.01, 100.0, 0.5)
obj.addProperty("App::PropertyFloat", "StartDepth", "Depth", translate("PathProject","Starting Depth of Tool- first cut depth in Z"))
obj.addProperty("App::PropertyFloat", "FinalDepth", "Depth", translate("PathProject","Final Depth of Tool- lowest value in Z"))
obj.addProperty("App::PropertyFloat", "FinishDepth", "Depth", translate("PathProject","Maximum material removed on final pass."))
#obj.addProperty("App::PropertyFloat", "RetractHeight", "Depth", translate("PathProject","The height desired to retract tool when path is finished"))
obj.addProperty("App::PropertyFloat", "ClearanceHeight", "Pocket","The height needed to clear clamps and obstructions")
obj.addProperty("App::PropertyFloatConstraint", "StepDown", "Pocket","Incremental Step Down of Tool")
obj.StepDown = (0.0, 0.0, 100.0, 1.0)
obj.addProperty("App::PropertyFloat", "StartDepth", "Pocket", "Starting Depth of Tool- first cut depth in Z")
obj.addProperty("App::PropertyBool","UseStartDepth","Pocket","make True, if manually specifying a Start Start Depth")
obj.addProperty("App::PropertyFloat", "FinalDepth", "Pocket", "Final Depth of Tool- lowest value in Z")
obj.addProperty("App::PropertyFloat", "RetractHeight", "Pocket", "The height desired to retract tool when path is finished")
obj.addProperty("App::PropertyEnumeration", "CutMode", "Pocket","The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW")
obj.CutMode = ['Climb','Conventional']
obj.addProperty("App::PropertyFloat", "MaterialAllowance", "Pocket", "Amount of material to leave")
obj.addProperty("App::PropertyFloat", "FinishDepth", "Pocket", "Maximum material removed on final pass.")
obj.addProperty("App::PropertyEnumeration", "StartAt", "Pocket","Start pocketing at center or boundary")
obj.StartAt = ['Center', 'Edge']
obj.addProperty("App::PropertyFloatConstraint", "VertFeed", "Feed","Feed rate for vertical moves in Z")
#Feed Properties
obj.addProperty("App::PropertyFloatConstraint", "VertFeed", "Feed",translate("Vert Feed","Feed rate for vertical moves in Z"))
obj.VertFeed = (0.0, 0.0, 100000.0, 1.0)
obj.addProperty("App::PropertyFloatConstraint", "HorizFeed", "Feed","Feed rate for horizontal moves")
obj.addProperty("App::PropertyFloatConstraint", "HorizFeed", "Feed",translate("Horiz Feed","Feed rate for horizontal moves"))
obj.HorizFeed = (0.0, 0.0, 100000.0, 1.0)
#Pocket Properties
obj.addProperty("App::PropertyEnumeration", "CutMode", "Pocket",translate("PathProject", "The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW"))
obj.CutMode = ['Climb','Conventional']
obj.addProperty("App::PropertyFloat", "MaterialAllowance", "Pocket", translate("PathProject","Amount of material to leave"))
obj.addProperty("App::PropertyEnumeration", "StartAt", "Pocket",translate("PathProject", "Start pocketing at center or boundary"))
obj.StartAt = ['Center', 'Edge']
obj.addProperty("App::PropertyFloatConstraint","StepOver","Pocket",translate("PathProject","Amount to step over on each pass"))
obj.StepOver = (0.0, 0.01, 100.0, 0.5)
obj.addProperty("App::PropertyBool","KeepToolDown","Pocket",translate("PathProject","Attempts to avoid unnecessary retractions."))
obj.addProperty("App::PropertyBool","ZigUnidirectional","Pocket",translate("PathProject","Lifts tool at the end of each pass to respect cut mode."))
obj.addProperty("App::PropertyBool","UseZigZag","Pocket",translate("PathProject","Use Zig Zag pattern to clear area."))
obj.addProperty("App::PropertyFloat","ZigZagAngle","Pocket",translate("PathProject","Angle of the zigzag pattern"))
#Entry Properties
obj.addProperty("App::PropertyBool","UseEntry","Entry",translate("PathProject","Allow Cutter enter material with a straight plunge."))
obj.addProperty("App::PropertyFloatConstraint", "RampSize", "Entry", translate("PathProject","The minimum fraction of tool diameter to use for ramp length"))
obj.RampSize = (0.0, 0.01, 100.0, 0.5)
obj.addProperty("App::PropertyFloatConstraint", "HelixSize", "Entry", translate("PathProject","The fraction of tool diameter to use for calculating helix size."))
obj.HelixSize = (0.0, 0.01, 100.0, 0.5)
obj.addProperty("App::PropertyFloatConstraint", "RampAngle", "Entry", translate("PathProject","The Angle of the ramp entry."))
obj.RampAngle = (0.0, 0.01, 100.0, 0.5)
obj.addProperty("App::PropertyBool","Active","Path","Make False, to prevent operation from generating code")
obj.addProperty("App::PropertyString","Comment","Path","An optional comment for this profile")
obj.Proxy = self
@ -127,53 +118,221 @@ class ObjectPocket:
return self.getStock(o)
return None
def buildpathlibarea(self, obj, a):
import PathScripts.PathUtils as PathUtils
import PathScripts.PathAreaUtils as PathAreaUtils
from PathScripts.PathUtils import depth_params
import area
FreeCAD.Console.PrintMessage(translate("PathPocket","Generating toolpath with libarea offsets.\n"))
depthparams = depth_params (obj.ClearanceHeight, obj.SafeHeight, obj.StartDepth, obj.StepDown, obj.FinishDepth, obj.FinalDepth)
horizfeed = obj.HorizFeed
extraoffset = obj.MaterialAllowance
stepover = obj.StepOver
use_zig_zag = obj.UseZigZag
zig_angle = obj.ZigZagAngle
from_center = (obj.StartAt == "Center")
keep_tool_down = obj.KeepToolDown
zig_unidirectional = obj.ZigUnidirectional
start_point = None
cut_mode = obj.CutMode
PathAreaUtils.output('mem')
print "a," + str(self.radius) + "," + str(extraoffset) + "," + str(stepover) + ",depthparams, " + str(from_center) + "," + str(keep_tool_down) + "," + str(use_zig_zag) + "," + str(zig_angle) + "," + str(zig_unidirectional) + "," + str(start_point) + "," + str(cut_mode)
PathAreaUtils.pocket(a,self.radius,extraoffset, stepover,depthparams,from_center,keep_tool_down,use_zig_zag,zig_angle,zig_unidirectional,start_point,cut_mode)
return PathAreaUtils.retrieve_gcode()
#To reload this from FreeCAD, use: import PathScripts.PathPocket; reload(PathScripts.PathPocket)
def execute(self,obj):
if obj.Base:
tool = PathUtils.getLastTool(obj)
if tool:
radius = tool.Diameter/2
if radius < 0:# safe guard
radius -= radius
def buildpathocc(self, obj, shape):
import Part, DraftGeomUtils
FreeCAD.Console.PrintMessage(translate("PathPocket","Generating toolpath with OCC native offsets.\n"))
def prnt(vlu): return str("%.4f" % round(vlu, 4))
def rapid(x=None, y=None, z=None):
#Returns gcode to perform a rapid move
retstr = "G00"
if (x != None) or (y != None) or (z != None):
if (x != None):
retstr += " X" + str("%.4f" % x)
if (y != None):
retstr += " Y" + str("%.4f" % y)
if (z != None):
retstr += " Z" + str("%.4f" % z)
else:
# temporary value, to be taken from the properties later on
radius = 1
return ""
return retstr + "\n"
import Part, DraftGeomUtils
if "Face" in obj.Base[1][0]:
shape = getattr(obj.Base[0].Shape,obj.Base[1][0])
def feed(x=None, y=None, z=None):
#Returns gcode to perform a linear feed
global feedxy
retstr = "G01 F"
if(x == None) and (y == None):
retstr += str("%.4f" % obj.HorizFeed)
else:
edges = [getattr(obj.Base[0].Shape,sub) for sub in obj.Base[1]]
shape = Part.Wire(edges)
print len(edges)
# absolute coords, millimeters, cancel offsets
output = "G90\nG21\nG40\n"
# save tool
if obj.ToolNumber > 0 and tool.ToolNumber != obj.ToolNumber:
output += "M06 T" + str(tool.ToolNumber) + "\n"
retstr += str("%.4f" % obj.VertFeed)
# build offsets
offsets = []
nextradius = radius
if (x != None) or (y != None) or (z != None):
if (x != None):
retstr += " X" + str("%.4f" % x)
if (y != None):
retstr += " Y" + str("%.4f" % y)
if (z != None):
retstr += " Z" + str("%.4f" % z)
else:
return ""
return retstr + "\n"
def arc(cx, cy, sx, sy, ex, ey, ez=None, ccw=False):
#Returns gcode to perform an arc
#Assumes XY plane or helix around Z
#Don't worry about starting Z- assume that's dealt with elsewhere
#If start/end radii aren't within eps, abort
eps = 0.01
if (math.sqrt((cx - sx)**2 + (cy - sy)**2) - math.sqrt((cx - ex)**2 + (cy - ey)**2)) >= eps:
print "ERROR: Illegal arc: Stand and end radii not equal"
return ""
#Set [C]CW and feed
retstr = ""
if ccw:
retstr += "G03 F"
else:
retstr += "G02 F"
retstr += str(obj.HorizFeed)
#End location
retstr += " X" + str("%.4f" % ex) + " Y" + str("%.4f" % ey)
#Helix if requested
if ez != None:
retstr += " Z" + str("%.4f" % ez)
#Append center offsets
retstr += " I" + str("%.4f" % (cx - sx)) + " J" + str("%.4f" % (cy - sy))
return retstr + "\n"
def helicalPlunge(plungePos, rampangle, destZ, startZ):
#Returns gcode to helically plunge
#destZ is the milling level
#startZ is the height we can safely feed down to before helix-ing
helixCmds = "(START HELICAL PLUNGE)\n"
if(plungePos == None):
raise Error("Helical plunging requires a position!")
return None
if(not tool):
raise Error("Helical plunging requires a tool!")
return None
helixX = plungePos.x + tool.Diameter/2. * plungeR
helixY = plungePos.y;
helixCirc = math.pi * tool.Diameter * plungeR
dzPerRev = math.sin(rampangle/180. * math.pi) * helixCirc
#Go to the start of the helix position
helixCmds += rapid(helixX, helixY)
helixCmds += rapid(z=startZ)
#Helix as required to get to the requested depth
lastZ = startZ
curZ = max(startZ-dzPerRev, destZ)
done = False
while not done:
done = (curZ == destZ)
#NOTE: FreeCAD doesn't render this, but at least LinuxCNC considers it valid
#helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX, helixY, ez = curZ, ccw=True)
#Use two half-helixes; FreeCAD renders that correctly,
#and it fits with the other code breaking up 360-degree arcs
helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX - tool.Diameter * plungeR, helixY, ez = (curZ + lastZ)/2., ccw=True)
helixCmds += arc(plungePos.x, plungePos.y, helixX - tool.Diameter * plungeR, helixY, helixX, helixY, ez = curZ, ccw=True)
lastZ = curZ
curZ = max(curZ - dzPerRev, destZ)
return helixCmds
def rampPlunge(edge, rampangle, destZ, startZ):
#Returns commands to linearly ramp into a cut
#FIXME: This ramps along the first edge, assuming it's long
#enough, NOT just wiggling back and forth by ~0.75 * toolD.
#Not sure if that's any worse, but it's simpler
# I think this should be changed to be limited to a maximum ramp size. Otherwise machine time will get longer than it needs to be.
rampCmds = "(START RAMP PLUNGE)\n"
if(edge == None):
raise Error("Ramp plunging requires an edge!")
return None
if(not tool):
raise Error("Ramp plunging requires a tool!")
sPoint = edge.Vertexes[0].Point
ePoint = edge.Vertexes[1].Point
#Evidently edges can get flipped- pick the right one in this case
#FIXME: This is iffy code, based on what already existed in the "for vpos ..." loop below
if ePoint == sPoint:
#print "FLIP"
ePoint = edge.Vertexes[-1].Point
#print "Start: " + str(sPoint) + " End: " + str(ePoint) + " Zhigh: " + prnt(startZ) + " ZLow: " + prnt(destZ)
rampDist = edge.Length
rampDZ = math.sin(rampangle/180. * math.pi) * rampDist
rampCmds += rapid(sPoint.x, sPoint.y)
rampCmds += rapid(z=startZ)
#Ramp down to the requested depth
#FIXME: This might be an arc, so handle that as well
lastZ = startZ
curZ = max(startZ-rampDZ, destZ)
done = False
while not done:
done = (curZ == destZ)
#If it's an arc, handle it!
if isinstance(edge.Curve,Part.Circle):
raise Error("rampPlunge: Screw it, not handling an arc.")
#Straight feed! Easy!
else:
rampCmds += feed(ePoint.x, ePoint.y, curZ)
rampCmds += feed(sPoint.x, sPoint.y)
lastZ = curZ
curZ = max(curZ - rampDZ, destZ)
return rampCmds
output = ""
offsets = []
nextradius = self.radius
result = DraftGeomUtils.pocket2d(shape,nextradius)
while result:
#print "Adding " + str(len(result)) + " wires"
offsets.extend(result)
nextradius += self.radius
result = DraftGeomUtils.pocket2d(shape,nextradius)
while result:
#print "Adding " + str(len(result)) + " wires"
offsets.extend(result)
nextradius += radius
result = DraftGeomUtils.pocket2d(shape,nextradius)
# first move will be rapid, subsequent will be at feed rate
first = True
startPoint = None
fastZPos = max(obj.StartDepth + 2, obj.RetractHeight)
# revert the list so we start with the outer wires
if obj.StartAt != 'Edge':
offsets.reverse()
# first move will be rapid, subsequent will be at feed rate
first = True
startPoint = None
fastZPos = max(obj.StartDepth + 2, obj.ClearanceHeight)
# revert the list so we start with the outer wires
if obj.StartAt != 'Edge':
offsets.reverse()
# print "startDepth: " + str(obj.StartDepth)
# print "finalDepth: " + str(obj.FinalDepth)
@ -181,291 +340,201 @@ class ObjectPocket:
# print "finishDepth" + str(obj.FinishDepth)
# print "offsets:", len(offsets)
def prnt(vlu): return str("%.4f" % round(vlu, 4))
#Fraction of tool radius our plunge helix is to be
#FIXME: This should be configurable
plungeR = 0.75
#(minimum) Fraction of tool DIAMETER to go back and forth while ramp-plunging
#FIXME: This should be configurable
#FIXME: The ramp plunging should maybe even be limited to this distance; I don't know what's best
rampD = 0.75
#Total offset from the desired pocket edge is tool radius plus the plunge helix radius
#Any point on these curves could be the center of a plunge
helixBounds = DraftGeomUtils.pocket2d(shape, tool.Diameter / 2. * (1 + plungeR))
#Try to find a location to nicely plunge, starting with a helix, then ramp
#Can't do it without knowledge of a tool
plungePos = None
rampEdge = None
if not tool:
raise Error("Ramp plunge location-finding requires a tool")
return
else:
#Since we're going to start machining either the inner-most
#edge or the outer (depending on StartAt setting), try to
#plunge near that location
if helixBounds:
#Edge is easy- pick a point on helixBounds and go with it
if obj.StartAt == 'Edge':
plungePos = helixBounds[0].Edges[0].Vertexes[0].Point
#Center is harder- use a point from the first offset, check if it works
else:
plungePos = offsets[0].Edges[0].Vertexes[0].Point
#If it turns out this is invalid for some reason, nuke plungePos
[perp,idx] = DraftGeomUtils.findPerpendicular(plungePos, shape.Edges)
if not perp or perp.Length < tool.Diameter / 2. * (1 + plungeR):
plungePos = None
#FIXME: Really need to do a point-in-polygon operation to make sure this is within helixBounds
#Or some math to prove that it has to be (doubt that's true)
#Maybe reverse helixBounds and pick off that?
#If we didn't find a place to helix, how about a ramp?
if not plungePos:
#Check first edge of our offsets
if (offsets[0].Edges[0].Length >= tool.Diameter * rampD) and not (isinstance(offsets[0].Edges[0].Curve, Part.Circle)):
rampEdge = offsets[0].Edges[0]
#The last edge also connects with the starting location- try that
elif (offsets[0].Edges[-1].Length >= tool.Diameter * rampD) and not (isinstance(offsets[0].Edges[-1].Curve, Part.Circle)):
rampEdge = offsets[0].Edges[-1]
else:
print "Neither edge works: " + str(offsets[0].Edges[0]) + ", " + str(offsets[0].Edges[-1])
#FIXME: There's got to be a smarter way to find a place to ramp
#Returns gcode to perform a rapid move
def rapid(x=None, y=None, z=None):
retstr = "G00"
if (x != None) or (y != None) or (z != None):
if (x != None):
retstr += " X" + str("%.4f" % x)
if (y != None):
retstr += " Y" + str("%.4f" % y)
if (z != None):
retstr += " Z" + str("%.4f" % z)
else:
return ""
return retstr + "\n"
#Returns gcode to perform a linear feed
def feed(x=None, y=None, z=None):
global feedxy
retstr = "G01 F"
if(x == None) and (y == None):
retstr += str("%.4f" % obj.HorizFeed)
else:
retstr += str("%.4f" % obj.VertFeed)
if (x != None) or (y != None) or (z != None):
if (x != None):
retstr += " X" + str("%.4f" % x)
if (y != None):
retstr += " Y" + str("%.4f" % y)
if (z != None):
retstr += " Z" + str("%.4f" % z)
else:
return ""
return retstr + "\n"
#Returns gcode to perform an arc
#Assumes XY plane or helix around Z
#Don't worry about starting Z- assume that's dealt with elsewhere
def arc(cx, cy, sx, sy, ex, ey, ez=None, ccw=False):
#If start/end radii aren't within eps, abort
eps = 0.01
if (math.sqrt((cx - sx)**2 + (cy - sy)**2) - math.sqrt((cx - ex)**2 + (cy - ey)**2)) >= eps:
print "ERROR: Illegal arc: Stand and end radii not equal"
return ""
#Set [C]CW and feed
retstr = ""
if ccw:
retstr += "G03 F"
else:
retstr += "G02 F"
retstr += str(obj.HorizFeed)
#End location
retstr += " X" + str("%.4f" % ex) + " Y" + str("%.4f" % ey)
#Helix if requested
if ez != None:
retstr += " Z" + str("%.4f" % ez)
#Append center offsets
retstr += " I" + str("%.4f" % (cx - sx)) + " J" + str("%.4f" % (cy - sy))
return retstr + "\n"
#Fraction of tool radius our plunge helix is to be
plungeR = obj.HelixSize
#(minimum) Fraction of tool DIAMETER to go back and forth while ramp-plunging
#FIXME: The ramp plunging should maybe even be limited to this distance; I don't know what's best
rampD = obj.RampSize
#Returns gcode to helically plunge
#destZ is the milling level
#startZ is the height we can safely feed down to before helix-ing
def helicalPlunge(plungePos, rampangle, destZ, startZ):
helixCmds = "(START HELICAL PLUNGE)\n"
if(plungePos == None):
raise Error("Helical plunging requires a position!")
return None
if(not tool):
raise Error("Helical plunging requires a tool!")
return None
helixX = plungePos.x + tool.Diameter/2. * plungeR
helixY = plungePos.y;
helixCirc = math.pi * tool.Diameter * plungeR
dzPerRev = math.sin(rampangle/180. * math.pi) * helixCirc
#Go to the start of the helix position
helixCmds += rapid(helixX, helixY)
helixCmds += rapid(z=startZ)
#Helix as required to get to the requested depth
lastZ = startZ
curZ = max(startZ-dzPerRev, destZ)
done = False
while not done:
done = (curZ == destZ)
#NOTE: FreeCAD doesn't render this, but at least LinuxCNC considers it valid
#helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX, helixY, ez = curZ, ccw=True)
#Total offset from the desired pocket edge is tool radius plus the plunge helix radius
#Any point on these curves could be the center of a plunge
helixBounds = DraftGeomUtils.pocket2d(shape, self.radius * (1 + plungeR))
#Try to find a location to nicely plunge, starting with a helix, then ramp
#Can't do it without knowledge of a tool
plungePos = None
rampEdge = None
tool = PathUtils.getTool(obj,obj.ToolNumber)
if not tool:
raise Error("Ramp plunge location-finding requires a tool")
return
else:
#Since we're going to start machining either the inner-most
#edge or the outer (depending on StartAt setting), try to
#plunge near that location
if helixBounds and obj.UseEntry:
#Edge is easy- pick a point on helixBounds and go with it
if obj.StartAt == 'Edge':
plungePos = helixBounds[0].Edges[0].Vertexes[0].Point
#Center is harder- use a point from the first offset, check if it works
else:
plungePos = offsets[0].Edges[0].Vertexes[0].Point
#Use two half-helixes; FreeCAD renders that correctly,
#and it fits with the other code breaking up 360-degree arcs
helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX - tool.Diameter * plungeR, helixY, ez = (curZ + lastZ)/2., ccw=True)
helixCmds += arc(plungePos.x, plungePos.y, helixX - tool.Diameter * plungeR, helixY, helixX, helixY, ez = curZ, ccw=True)
lastZ = curZ
curZ = max(curZ - dzPerRev, destZ)
return helixCmds
#Returns commands to linearly ramp into a cut
#FIXME: This ramps along the first edge, assuming it's long
#enough, NOT just wiggling back and forth by ~0.75 * toolD.
#Not sure if that's any worse, but it's simpler
#FIXME: This code is untested
def rampPlunge(edge, rampangle, destZ, startZ):
rampCmds = "(START RAMP PLUNGE)\n"
if(edge == None):
raise Error("Ramp plunging requires an edge!")
return None
if(not tool):
raise Error("Ramp plunging requires a tool!")
sPoint = edge.Vertexes[0].Point
ePoint = edge.Vertexes[1].Point
#Evidently edges can get flipped- pick the right one in this case
#FIXME: This is iffy code, based on what already existed in the "for vpos ..." loop below
if ePoint == sPoint:
#print "FLIP"
ePoint = edge.Vertexes[-1].Point
#print "Start: " + str(sPoint) + " End: " + str(ePoint) + " Zhigh: " + prnt(startZ) + " ZLow: " + prnt(destZ)
rampDist = edge.Length
rampDZ = math.sin(rampangle/180. * math.pi) * rampDist
rampCmds += rapid(sPoint.x, sPoint.y)
rampCmds += rapid(z=startZ)
#Ramp down to the requested depth
#FIXME: This might be an arc, so handle that as well
lastZ = startZ
curZ = max(startZ-rampDZ, destZ)
done = False
while not done:
done = (curZ == destZ)
#If it's an arc, handle it!
if isinstance(edge.Curve,Part.Circle):
raise Error("rampPlunge: Screw it, not handling an arc.")
#Straight feed! Easy!
else:
rampCmds += feed(ePoint.x, ePoint.y, curZ)
rampCmds += feed(sPoint.x, sPoint.y)
#If it turns out this is invalid for some reason, nuke plungePos
[perp,idx] = DraftGeomUtils.findPerpendicular(plungePos, shape.Edges)
if not perp or perp.Length < self.radius * (1 + plungeR):
plungePos = None
#FIXME: Really need to do a point-in-polygon operation to make sure this is within helixBounds
#Or some math to prove that it has to be (doubt that's true)
#Maybe reverse helixBounds and pick off that?
#If we didn't find a place to helix, how about a ramp?
if not plungePos and obj.UseEntry:
#Check first edge of our offsets
if (offsets[0].Edges[0].Length >= tool.Diameter * rampD) and not (isinstance(offsets[0].Edges[0].Curve, Part.Circle)):
rampEdge = offsets[0].Edges[0]
#The last edge also connects with the starting location- try that
elif (offsets[0].Edges[-1].Length >= tool.Diameter * rampD) and not (isinstance(offsets[0].Edges[-1].Curve, Part.Circle)):
rampEdge = offsets[0].Edges[-1]
else:
print "Neither edge works: " + str(offsets[0].Edges[0]) + ", " + str(offsets[0].Edges[-1])
#FIXME: There's got to be a smarter way to find a place to ramp
lastZ = curZ
curZ = max(curZ - rampDZ, destZ)
return rampCmds
#For helix-ing/ramping, know where we were last time
#FIXME: Can probably get this from the "machine"?
lastZ = fastZPos
#For helix-ing/ramping, know where we were last time
#FIXME: Can probably get this from the "machine"?
lastZ = fastZPos
for vpos in frange(obj.StartDepth, obj.FinalDepth, obj.StepDown, obj.FinishDepth):
# print "vpos: " + str(vpos)
#Every for every depth we should helix down
first = True
# loop over successive wires
for currentWire in offsets:
# print "new line (offset)"
last = None
for edge in currentWire.Edges:
# print "new edge"
if not last:
# we set the base GO to our fast move to our starting pos
if first:
#If we can helix, do so
if plungePos:
output += helicalPlunge(plungePos, 3, vpos, lastZ)
#print output
lastZ = vpos
#Otherwise, see if we can ramp
#FIXME: This could be a LOT smarter (eg, searching for a longer leg of the edge to ramp along)
elif rampEdge:
output += rampPlunge(rampEdge, 3, vpos, lastZ)
lastZ = vpos
#Otherwise, straight plunge... Don't want to, but sometimes you might not have a choice.
#FIXME: At least not with the lazy ramp programming above...
else:
print "WARNING: Straight-plunging... probably not good, but we didn't find a place to helix or ramp"
startPoint = edge.Vertexes[0].Point
output += "G0 X" + prnt(startPoint.x) + " Y" + prnt(startPoint.y) +\
" Z" + prnt(fastZPos) + "\n"
first = False
#then move slow down to our starting point for our profile
last = edge.Vertexes[0].Point
output += "G1 X" + prnt(last.x) + " Y" + prnt(last.y) + " Z" + prnt(vpos) + "\n"
#if isinstance(edge.Curve,Part.Circle):
if DraftGeomUtils.geomType(edge) == "Circle":
point = edge.Vertexes[-1].Point
if point == last: # edges can come flipped
point = edge.Vertexes[0].Point
# print "flipped"
center = edge.Curve.Center
relcenter = center.sub(last)
v1 = last.sub(center)
v2 = point.sub(center)
if v1.cross(v2).z < 0:
output += "G2"
for vpos in PathUtils.frange(obj.StartDepth, obj.FinalDepth, obj.StepDown, obj.FinishDepth):
#Every for every depth we should helix down
first = True
# loop over successive wires
for currentWire in offsets:
last = None
for edge in currentWire.Edges:
if not last:
# we set the base GO to our fast move to our starting pos
if first:
#If we can helix, do so
if plungePos:
output += helicalPlunge(plungePos, obj.RampAngle, vpos, lastZ)
#print output
lastZ = vpos
#Otherwise, see if we can ramp
#FIXME: This could be a LOT smarter (eg, searching for a longer leg of the edge to ramp along)
elif rampEdge:
output += rampPlunge(rampEdge, obj.RampAngle, vpos, lastZ)
lastZ = vpos
#Otherwise, straight plunge... Don't want to, but sometimes you might not have a choice.
#FIXME: At least not with the lazy ramp programming above...
else:
output += "G3"
output += " X" + prnt(point.x) + " Y" + prnt(point.y) + " Z" + prnt(vpos)
output += " I" + prnt(relcenter.x) + " J" +prnt(relcenter.y) + " K" + prnt(relcenter.z)
output += "\n"
last = point
print "WARNING: Straight-plunging... probably not good, but we didn't find a place to helix or ramp"
startPoint = edge.Vertexes[0].Point
output += "G0 X" + prnt(startPoint.x) + " Y" + prnt(startPoint.y) +\
" Z" + prnt(fastZPos) + "\n"
first = False
#then move slow down to our starting point for our profile
last = edge.Vertexes[0].Point
output += "G1 X" + prnt(last.x) + " Y" + prnt(last.y) + " Z" + prnt(vpos) + "\n"
#if isinstance(edge.Curve,Part.Circle):
if DraftGeomUtils.geomType(edge) == "Circle":
point = edge.Vertexes[-1].Point
if point == last: # edges can come flipped
point = edge.Vertexes[0].Point
center = edge.Curve.Center
relcenter = center.sub(last)
v1 = last.sub(center)
v2 = point.sub(center)
if v1.cross(v2).z < 0:
output += "G2"
else:
point = edge.Vertexes[-1].Point
if point == last: # edges can come flipped
point = edge.Vertexes[0].Point
output += "G1 X" + prnt(point.x) + " Y" + prnt(point.y) + " Z" + prnt(vpos) + "\n"
last = point
output += "G3"
output += " X" + prnt(point.x) + " Y" + prnt(point.y) + " Z" + prnt(vpos)
output += " I" + prnt(relcenter.x) + " J" +prnt(relcenter.y) + " K" + prnt(relcenter.z)
output += "\n"
last = point
else:
point = edge.Vertexes[-1].Point
if point == last: # edges can come flipped
point = edge.Vertexes[0].Point
output += "G1 X" + prnt(point.x) + " Y" + prnt(point.y) + " Z" + prnt(vpos) + "\n"
last = point
#move back up
output += "G1 Z" + prnt(fastZPos) + "\n"
return output
#To reload this from FreeCAD, use: import PathScripts.PathPocket; reload(PathScripts.PathPocket)
def execute(self,obj):
if obj.Base:
import Part, PathScripts.PathKurveUtils, DraftGeomUtils
if "Face" in obj.Base[1][0]:
shape = getattr(obj.Base[0].Shape,obj.Base[1][0])
wire = shape.OuterWire
edges = wire.Edges
else:
edges = [getattr(obj.Base[0].Shape,sub) for sub in obj.Base[1]]
print "myedges: " + str(edges)
wire = Part.Wire(edges)
shape = None
# tie the toolnumber to the PathLoadTool object ToolNumber
if len(obj.InList)>0: #check to see if obj is in the Project group yet
project = obj.InList[0]
tl = int(PathUtils.changeTool(obj,project))
obj.ToolNumber= tl
tool = PathUtils.getTool(obj,obj.ToolNumber)
if tool:
self.radius = tool.Diameter/2
else:
# temporary value,in case we don't have any tools defined already
self.radius = 0.25
output = ""
if obj.Algorithm == "OCC Native":
if shape == None:
shape = wire
output += self.buildpathocc(obj, shape)
else:
try:
import area
except:
FreeCAD.Console.PrintError(translate("PathKurve","libarea needs to be installed for this command to work.\n"))
return
a = area.Area()
if shape == None:
c = PathScripts.PathKurveUtils.makeAreaCurve(wire.Edges, 'CW')
a.append(c)
else:
for w in shape.Wires:
c = PathScripts.PathKurveUtils.makeAreaCurve(w.Edges, 'CW')
# if w.isSame(shape.OuterWire):
# print "outerwire"
# if c.IsClockwise():
# c.Reverse()
# print "reverse outterwire"
# else:
# print "inner wire"
# if not c.IsClockwise():
# c.Reverse()
# print "reverse inner"
a.append(c)
########
##This puts out some interesting information from libarea
print a.text()
########
a.Reorder()
output += self.buildpathlibarea(obj, a)
if obj.UseEntry:
obj.setEditorMode('HelixSize',0) #make this visible
obj.setEditorMode('RampAngle',0) #make this visible
obj.setEditorMode('RampSize',0) #make this visible
else:
obj.setEditorMode('HelixSize',2) #make this hidden
obj.setEditorMode('RampAngle',2) #make this hidden
obj.setEditorMode('RampSize',2) #make this hidden
#move back up
output += "G0 Z" + prnt(fastZPos) + "\n"
# print output
# path = Path.Path(output)
# obj.Path = path
if obj.Active:
path = Path.Path(output)
obj.Path = path
@ -500,62 +569,80 @@ class CommandPathPocket:
def GetResources(self):
return {'Pixmap' : 'Path-Pocket',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Pocket","Pocket"),
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathPocket","Pocket"),
'Accel': "P, O",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Pocket","Creates a Path Pocket object from a loop of edges or a face")}
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathPocket","Creates a Path Pocket object from a loop of edges or a face")}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def Activated(self):
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelectionEx()
if len(selection) != 1:
FreeCAD.Console.PrintError(translate("Path_Pocket","Please select an edges loop from one object, or a single face\n"))
FreeCAD.Console.PrintError(translate("PathPocket","Please select an edges loop from one object, or a single face\n"))
return
if len(selection[0].SubObjects) == 0:
FreeCAD.Console.PrintError(translate("Path_Pocket","Please select an edges loop from one object, or a single face\n"))
FreeCAD.Console.PrintError(translate("PathPocket","Please select an edges loop from one object, or a single face\n"))
return
for s in selection[0].SubObjects:
if s.ShapeType != "Edge":
if (s.ShapeType != "Face") or (len(selection[0].SubObjects) != 1):
FreeCAD.Console.PrintError(translate("Path_Pocket","Please select only edges or a single face\n"))
FreeCAD.Console.PrintError(translate("PathPocket","Please select only edges or a single face\n"))
return
if selection[0].SubObjects[0].ShapeType == "Edge":
try:
import Part
w = Part.Wire(selection[0].SubObjects)
if w.isClosed() == False:
FreeCAD.Console.PrintError(translate("PathPocket","The selected edges don't form a loop\n"))
return
except:
FreeCAD.Console.PrintError(translate("Path_Pocket","The selected edges don't form a loop\n"))
FreeCAD.Console.PrintError(translate("PathPocket","The selected edges don't form a loop\n"))
return
# Take a guess at some reasonable values for Finish depth.
bb = selection[0].Object.Shape.BoundBox #parent boundbox
fbb = selection[0].SubObjects[0].BoundBox #feature boundbox
if fbb.ZMax < bb.ZMax:
zbottom = fbb.ZMax
else:
zbottom = bb.ZMin
# if everything is ok, execute and register the transaction in the undo/redo stack
FreeCAD.ActiveDocument.openTransaction(translate("Path_Pocket","Create Pocket"))
FreeCAD.ActiveDocument.openTransaction(translate("PathPocket","Create Pocket"))
FreeCADGui.addModule("PathScripts.PathPocket")
FreeCADGui.doCommand('prjexists = False')
FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Pocket")')
FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Pocket")')
FreeCADGui.doCommand('PathScripts.PathPocket.ObjectPocket(obj)')
FreeCADGui.doCommand('obj.Active = True')
FreeCADGui.doCommand('PathScripts.PathPocket.ViewProviderPocket(obj.ViewObject)')
subs = "["
for s in selection[0].SubElementNames:
subs += '"' + s + '",'
subs += "]"
FreeCADGui.doCommand('obj.Base = (FreeCAD.ActiveDocument.' + selection[0].ObjectName + ',' + subs + ')')
FreeCADGui.doCommand('obj.Active = True')
snippet = '''
from PathScripts import PathUtils
PathUtils.addToProject(obj)
FreeCADGui.doCommand('from PathScripts import PathUtils')
ZMax = obj.Base[0].Shape.BoundBox.ZMax
ZMin = obj.Base[0].Shape.BoundBox.ZMin
obj.StepDown = 1.0
obj.StartDepth = ZMax
obj.FinalDepth = ZMin
obj.ClearanceHeight = ZMax + 5.0
FreeCADGui.doCommand('obj.StepOver = 1.0')
FreeCADGui.doCommand('obj.ClearanceHeight = ' + str(bb.ZMax + 2.0))
FreeCADGui.doCommand('obj.StepDown = 1.0')
FreeCADGui.doCommand('obj.StartDepth= ' + str(bb.ZMax))
FreeCADGui.doCommand('obj.FinalDepth=' + str(zbottom))
FreeCADGui.doCommand('obj.ZigZagAngle=45')
FreeCADGui.doCommand('obj.UseEntry=True')
FreeCADGui.doCommand('obj.RampAngle = 3.0')
FreeCADGui.doCommand('obj.RampSize = 0.75')
FreeCADGui.doCommand('obj.HelixSize = 0.75')
FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)')
'''
FreeCADGui.doCommand(snippet)
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()

View File

@ -226,6 +226,8 @@ class ObjectProfile:
curve = PathKurveUtils.makeAreaCurve(edgelist,direction,startpoint, endpoint)
'''The following line uses a profile function written for use with FreeCAD. It's clean but incomplete. It doesn't handle
print "x = " + str(point.x)
print "y - " + str(point.y)
holding tags
start location
CRC
@ -288,6 +290,78 @@ class ObjectProfile:
# return None
class _CommandAddTag:
def GetResources(self):
return {'Pixmap' : 'Path-Holding',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Profile","Add Holding Tag"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Profile","Add Holding Tag")}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def setpoint(self,point,o):
obj=FreeCADGui.Selection.getSelection()[0]
obj.StartPoint.x = point.x
obj.StartPoint.y = point.y
loc = obj.locs
h = obj.heights
l = obj.lengths
a = obj.angles
x = point.x
y = point.y
z = float(0.0)
loc.append(Vector(x,y,z))
h.append(4.0)
l.append(5.0)
a.append(45.0)
obj.locs = loc
obj.heights = h
obj.lengths = l
obj.angles = a
def Activated(self):
FreeCADGui.Snapper.getPoint(callback=self.setpoint)
class _CommandSetStartPoint:
def GetResources(self):
return {'Pixmap' : 'Path-Holding',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Profile","Pick Start Point"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Profile","Pick Start Point")}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def setpoint(self,point,o):
obj=FreeCADGui.Selection.getSelection()[0]
obj.StartPoint.x = point.x
obj.StartPoint.y = point.y
def Activated(self):
FreeCADGui.Snapper.getPoint(callback=self.setpoint)
class _CommandSetEndPoint:
def GetResources(self):
return {'Pixmap' : 'Path-Holding',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Profile","Pick End Point"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Profile","Pick End Point")}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def setpoint(self,point,o):
obj=FreeCADGui.Selection.getSelection()[0]
obj.EndPoint.x = point.x
obj.EndPoint.y = point.y
def Activated(self):
FreeCADGui.Snapper.getPoint(callback=self.setpoint)
class CommandPathProfile:
def GetResources(self):
return {'Pixmap' : 'Path-Profile',
@ -568,5 +642,8 @@ class _EditPanel:
if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand('Path_Profile',CommandPathProfile())
FreeCADGui.addCommand('Add_Tag',_CommandAddTag())
FreeCADGui.addCommand('Set_StartPoint',_CommandSetStartPoint())
FreeCADGui.addCommand('Set_EndPoint',_CommandSetEndPoint())
FreeCAD.Console.PrintLog("Loading PathProfile... done\n")

View File

@ -405,15 +405,9 @@ def frange(start, stop, step, finish):
curdepth = stop
x.append(curdepth)
# Why this?
# if start >= stop:
# start = stop
# x.append (start)
return x
class depth_params:
def __init__(self, clearance_height, rapid_safety_space, start_depth, step_down, z_finish_depth, final_depth, user_depths=None):
self.clearance_height = clearance_height
@ -425,6 +419,7 @@ class depth_params:
self.user_depths = user_depths
def get_depths(self):
print "in function"
depths = []
if self.user_depths != None:
depths = self.user_depths
@ -440,23 +435,7 @@ class depth_params:
for i in range(1, layer_count):
depth += layer_depth
depths.append(depth)
depths.reverse()
return depths
# def get_depths(start_depth, final_depth, step_down, z_finish_depth):
# '''get_depths returns a list of z heights for pocket clearing. First value is Z depth of the first pass, etc.
# start_depth: starting depth of pocket
# step_down: max amount removed per pocket pass
# z_finish_depth: amount to remove on last (finishing) pass
# final_depth: bottom of pocket'''
# depths = [depth]
# depth += z_finish_depth
# if depth + 0.0000001 < start_depth:
# if z_finish_depth > 0.0000001: depths.insert(0, depth)
# layer_count = int((start_depth - depth) / step_down - 0.0000001) + 1
# if layer_count > 0:
# layer_depth = (start_depth - depth)/layer_count
# for i in range(1, layer_count):
# depth += layer_depth
# depths.insert(0, depth)
# return depths

View File

@ -548,7 +548,7 @@ class Creator(nc.Creator):
## Moves
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None ):
if self.same_xyz(x, y, z, a, b, c): return
#if self.same_xyz(x, y, z, a, b, c): return
self.on_move()
if self.g0123_modal: