diff --git a/src/Mod/Path/PathScripts/PathDrilling.py b/src/Mod/Path/PathScripts/PathDrilling.py index c9c036f1f..702c86141 100644 --- a/src/Mod/Path/PathScripts/PathDrilling.py +++ b/src/Mod/Path/PathScripts/PathDrilling.py @@ -76,12 +76,19 @@ class ObjectDrilling: if toolLoad == None: self.vertFeed = 100 self.horizFeed = 100 + self.radius = 0.25 obj.ToolNumber= 0 else: self.vertFeed = toolLoad.VertFeed.Value self.horizFeed = toolLoad.HorizFeed.Value - tool = PathUtils.getTool(obj, toolLoad.ToolNumber) obj.ToolNumber= toolLoad.ToolNumber + + tool = PathUtils.getTool(obj, toolLoad.ToolNumber) + if tool == None: + self.radius = 0.25 + else: + self.radius = tool.Diameter/2 + if obj.Base: locations = [] for loc in obj.Base: diff --git a/src/Mod/Path/PathScripts/PathEngrave.py b/src/Mod/Path/PathScripts/PathEngrave.py index 6d3cef493..2865ff686 100644 --- a/src/Mod/Path/PathScripts/PathEngrave.py +++ b/src/Mod/Path/PathScripts/PathEngrave.py @@ -85,10 +85,14 @@ class ObjectPathEngrave: else: self.vertFeed = toolLoad.VertFeed.Value self.horizFeed = toolLoad.HorizFeed.Value - tool = PathUtils.getTool(obj, toolLoad.ToolNumber) - self.radius = tool.Diameter/2 obj.ToolNumber= toolLoad.ToolNumber + tool = PathUtils.getTool(obj, toolLoad.ToolNumber) + if tool == None: + self.radius = 0.25 + else: + self.radius = tool.Diameter/2 + if obj.Base: for o in obj.Base: output += "G0 " + str(obj.ClearanceHeight.Value)+"\n" diff --git a/src/Mod/Path/PathScripts/PathPocket.py b/src/Mod/Path/PathScripts/PathPocket.py index 9a977d306..d1a82c1a3 100644 --- a/src/Mod/Path/PathScripts/PathPocket.py +++ b/src/Mod/Path/PathScripts/PathPocket.py @@ -199,7 +199,7 @@ class ObjectPocket: return PathAreaUtils.retrieve_gcode() - + #@do_cprofile def buildpathocc(self, obj, shape): import Part, DraftGeomUtils FreeCAD.Console.PrintMessage(translate("PathPocket","Generating toolpath with OCC native offsets.\n")) @@ -274,18 +274,17 @@ class ObjectPocket: #Returns gcode to helically plunge #destZ is the milling level #startZ is the height we can safely feed down to before helix-ing + toold = self.radius * 2 + helixCmds = "(START HELICAL PLUNGE)\n" if(plungePos == None): raise Exception("Helical plunging requires a position!") return None - if(not tool): - raise Exception("Helical plunging requires a tool!") - return None - helixX = plungePos.x + tool.Diameter/2. * plungeR + helixX = plungePos.x + toold/2 * plungeR helixY = plungePos.y; - helixCirc = math.pi * tool.Diameter * plungeR + helixCirc = math.pi * toold * plungeR dzPerRev = math.sin(rampangle/180. * math.pi) * helixCirc #Go to the start of the helix position @@ -303,8 +302,8 @@ class ObjectPocket: #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) + helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX - toold * plungeR, helixY, ez = (curZ + lastZ)/2., ccw=True) + helixCmds += arc(plungePos.x, plungePos.y, helixX - toold * plungeR, helixY, helixX, helixY, ez = curZ, ccw=True) lastZ = curZ curZ = max(curZ - dzPerRev, destZ) @@ -317,14 +316,10 @@ class ObjectPocket: #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 Exception("Ramp plunging requires an edge!") return None - if(not tool): - raise Exception("Ramp plunging requires a tool!") - sPoint = edge.Vertexes[0].Point ePoint = edge.Vertexes[1].Point @@ -333,7 +328,6 @@ class ObjectPocket: 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 @@ -361,6 +355,10 @@ class ObjectPocket: return rampCmds + +#### Start Processing Path Data here. + + ###Build up the offset loops output = "" offsets = [] nextradius = self.radius @@ -372,20 +370,20 @@ class ObjectPocket: nextradius += self.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.Value + 2, obj.ClearanceHeight.Value) - # revert the list so we start with the outer wires if obj.StartAt != 'Edge': offsets.reverse() -# print "startDepth: " + str(obj.StartDepth.Value) -# print "finalDepth: " + str(obj.FinalDepth.Value) -# print "stepDown: " + str(obj.StepDown) -# print "finishDepth" + str(obj.FinishDepth.Value) -# print "offsets:", len(offsets) + ####loops built + + # first move will be rapid, subsequent will be at feed rate + first = True + startPoint = None + + + ##This should probably just be clearanceheight. + fastZPos = max(obj.StartDepth.Value + 2, obj.ClearanceHeight.Value) + #Fraction of tool radius our plunge helix is to be plungeR = obj.HelixSize @@ -403,42 +401,39 @@ class ObjectPocket: #Can't do it without knowledge of a tool plungePos = None rampEdge = None - tool = PathUtils.getTool(obj,obj.ToolNumber) - if not tool: - raise Exception("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 - #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? + #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 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 + 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 + + #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 >= toold * 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 >= toold * 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 #For helix-ing/ramping, know where we were last time #FIXME: Can probably get this from the "machine"? @@ -512,14 +507,18 @@ class ObjectPocket: self.vertFeed = 100 self.horizFeed = 100 self.radius = 0.25 - obj.ToolNumber = 0 + obj.ToolNumber= 0 else: self.vertFeed = toolLoad.VertFeed.Value self.horizFeed = toolLoad.HorizFeed.Value - tool = PathUtils.getTool(obj, toolLoad.ToolNumber) - self.radius = tool.Diameter/2 obj.ToolNumber= toolLoad.ToolNumber + tool = PathUtils.getTool(obj, toolLoad.ToolNumber) + if tool == None: + self.radius = 0.25 + else: + self.radius = tool.Diameter/2 + if obj.Base: for b in obj.Base: diff --git a/src/Mod/Path/PathScripts/PathSurface.py b/src/Mod/Path/PathScripts/PathSurface.py index f7d2b4463..e9d44878c 100644 --- a/src/Mod/Path/PathScripts/PathSurface.py +++ b/src/Mod/Path/PathScripts/PathSurface.py @@ -249,10 +249,14 @@ class ObjectSurface: else: self.vertFeed = toolLoad.VertFeed.Value self.horizFeed = toolLoad.HorizFeed.Value - tool = PathUtils.getTool(obj, toolLoad.ToolNumber) - self.radius = tool.Diameter/2 obj.ToolNumber= toolLoad.ToolNumber + tool = PathUtils.getTool(obj, toolLoad.ToolNumber) + if tool == None: + self.radius = 0.25 + else: + self.radius = tool.Diameter/2 + if obj.Base: for b in obj.Base: diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 7addc8c1d..3e497fdd6 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -33,6 +33,8 @@ import DraftVecUtils import PathScripts from PathScripts import PathProject + + def cleanedges(splines,precision): '''cleanedges([splines],precision). Convert BSpline curves, Beziers, to arcs that can be used for cnc paths. Returns Lines as is. Filters Circle and Arcs for over 180 degrees. Discretizes Ellipses. Ignores other geometry. ''' @@ -51,18 +53,18 @@ def cleanedges(splines,precision): elif geomType(spline)=="Ellipse": edges = curvetowire(spline, 1.0) #fixme hardcoded value - + elif geomType(spline)=="Circle": arcs=filterArcs(spline) for i in arcs: edges.append(Part.Edge(i)) - + elif geomType(spline)=="Line": edges.append(spline) - + else: pass - + return edges def curvetowire(obj,steps): @@ -244,7 +246,7 @@ def SortPath(wire,Side,radius,clockwise,firstedge=None,SegLen =0.5): preoffset= [] for e in newedgelist: if clockwise: - r = reverseEdge(e) + r = reverseEdge(e) preoffset.append(r) else: preoffset.append(e) @@ -334,7 +336,7 @@ def getLastTool(obj): def getLastToolLoad(obj): #This walks up the hierarchy and tries to find the closest preceding toolchange. - + import PathScripts tc = None lastfound = None @@ -364,7 +366,7 @@ def getLastToolLoad(obj): return tc if tc == None: - for g in FreeCAD.ActiveDocument.Objects: #top level object + for g in FreeCAD.ActiveDocument.Objects: #top level object if isinstance(g.Proxy,PathScripts.PathLoadTool.LoadTool): lastfound = g if g == obj: @@ -454,7 +456,7 @@ class depth_params: self.z_finish_depth = math.fabs(z_finish_depth) self.final_depth = final_depth self.user_depths = user_depths - + def get_depths(self): depths = [] if self.user_depths != None: @@ -473,5 +475,3 @@ class depth_params: depths.append(depth) depths.reverse() return depths - -