def getLeadStart(self, obj, queue, action): '''returns Lead In G-code.''' global currLocation results = [] # zdepth = currLocation["Z"] op = PathDressup.baseOp(obj.Base) tc = PathDressup.toolController(obj.Base) horizFeed = tc.HorizFeed.Value vertFeed = tc.VertFeed.Value toolnummer = tc.ToolNumber # set the correct twist command if self.getDirectionOfPath(obj) == 'left': arcdir = "G3" else: arcdir = "G2" R = obj.Length.Value # Radius of roll or length if queue[1].Name == "G1": # line p0 = queue[0].Placement.Base p1 = queue[1].Placement.Base v = self.normalize(p1.sub(p0)) # PathLog.notice(" CURRENT_IN : P0 Z:{} p1 Z:{}".format(p0.z,p1.z)) else: p0 = queue[0].Placement.Base p1 = queue[1].Placement.Base # PathLog.notice(" CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format(p0.x,p0.y,p1.x,p1.y)) v = self.normalize(p1.sub(p0)) if self.getDirectionOfPath(obj) == 'right': off_v = FreeCAD.Vector(v.y*R, -v.x*R, 0.0) else: off_v = FreeCAD.Vector(-v.y*R, v.x*R, 0.0) offsetvector = FreeCAD.Vector(v.x*R, v.y*R, 0) # IJ if obj.RadiusCenter == 'Radius': leadstart = (p0.add(off_v)).sub(offsetvector) # Rmode else: leadstart = p0.add(off_v) # Dmode if action == 'start': extendcommand = Path.Command('G0', {"X": 0.0, "Y": 0.0, "Z": op.ClearanceHeight.Value}) results.append(extendcommand) extendcommand = Path.Command('G0', {"X": leadstart.x, "Y": leadstart.y, "Z": op.ClearanceHeight.Value}) results.append(extendcommand) extendcommand = Path.Command('G0', {"X": leadstart.x, "Y": leadstart.y, "Z": op.SafeHeight.Value}) results.append(extendcommand) if action == 'layer': if not obj.KeepToolDown: extendcommand = Path.Command('G0', {"Z": op.SafeHeight.Value}) results.append(extendcommand) extendcommand = Path.Command('G0', {"X": leadstart.x, "Y": leadstart.y}) results.append(extendcommand) extendcommand = Path.Command('G1', {"X": leadstart.x, "Y": leadstart.y, "Z": p1.z, "F": vertFeed}) results.append(extendcommand) if obj.UseMashineCRC: if self.getDirectionOfPath(obj) == 'right': results.append(Path.Command('G42', {'D': toolnummer})) else: results.append(Path.Command('G41', {'D': toolnummer})) if obj.StyleOn == 'Arc': arcmove = Path.Command(arcdir, {"X": p0.x, "Y": p0.y, "I": offsetvector.x, "J": offsetvector.y, "F": horizFeed}) # add G2/G3 move results.append(arcmove) elif obj.StyleOn == 'Tangent': extendcommand = Path.Command('G1', {"X": p0.x, "Y": p0.y, "F": horizFeed}) results.append(extendcommand) else: PathLog.notice(" CURRENT_IN Perp") return results
def getDirectionOfPath(self, obj): op = PathDressup.baseOp(obj.Base) if hasattr(op, 'Side') and op.Side == 'Outside': if hasattr(op, 'Direction') and op.Direction == 'CW': return 'left' else: return 'right' else: if hasattr(op, 'Direction') and op.Direction == 'CW': return 'right' return 'left'
def getDirectionOfPath(self, obj): op = PathDressup.baseOp(obj.Base) if hasattr(op, "Side") and op.Side == "Outside": if hasattr(op, "Direction") and op.Direction == "CW": return "left" else: return "right" else: if hasattr(op, "Direction") and op.Direction == "CW": return "right" return "left"
def getLeadStart(self, obj, queue, action): '''returns Lead In G-code.''' global currLocation results = [] # zdepth = currLocation["Z"] op = PathDressup.baseOp(obj.Base) tc = PathDressup.toolController(obj.Base) horizFeed = tc.HorizFeed.Value vertFeed = tc.VertFeed.Value toolnummer = tc.ToolNumber # set the correct twist command if self.getDirectionOfPath(obj) == 'left': arcdir = "G3" else: arcdir = "G2" R = obj.Length.Value # Radius of roll or length if queue[1].Name == "G1": # line p0 = queue[0].Placement.Base p1 = queue[1].Placement.Base v = self.normalize(p1.sub(p0)) # PathLog.notice(" CURRENT_IN : P0 Z:{} p1 Z:{}".format(p0.z,p1.z)) else: p0 = queue[0].Placement.Base p1 = queue[1].Placement.Base # PathLog.notice(" CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format(p0.x,p0.y,p1.x,p1.y)) v = self.normalize(p1.sub(p0)) if self.getDirectionOfPath(obj) == 'right': off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0) else: off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0) offsetvector = FreeCAD.Vector(v.x * R, v.y * R, 0) # IJ if obj.RadiusCenter == 'Radius': leadstart = (p0.add(off_v)).sub(offsetvector) # Rmode else: leadstart = p0.add(off_v) # Dmode if action == 'start': extendcommand = Path.Command('G0', { "X": 0.0, "Y": 0.0, "Z": op.ClearanceHeight.Value }) results.append(extendcommand) extendcommand = Path.Command('G0', { "X": leadstart.x, "Y": leadstart.y, "Z": op.ClearanceHeight.Value }) results.append(extendcommand) extendcommand = Path.Command('G0', { "X": leadstart.x, "Y": leadstart.y, "Z": op.SafeHeight.Value }) results.append(extendcommand) if action == 'layer': if not obj.KeepToolDown: extendcommand = Path.Command('G0', {"Z": op.SafeHeight.Value}) results.append(extendcommand) extendcommand = Path.Command('G0', { "X": leadstart.x, "Y": leadstart.y }) results.append(extendcommand) extendcommand = Path.Command('G1', { "X": leadstart.x, "Y": leadstart.y, "Z": p1.z, "F": vertFeed }) results.append(extendcommand) if obj.UseMashineCRC: if self.getDirectionOfPath(obj) == 'right': results.append(Path.Command('G42', {'D': toolnummer})) else: results.append(Path.Command('G41', {'D': toolnummer})) if obj.StyleOn == 'Arc': arcmove = Path.Command( arcdir, { "X": p0.x, "Y": p0.y, "I": offsetvector.x, "J": offsetvector.y, "F": horizFeed }) # add G2/G3 move results.append(arcmove) elif obj.StyleOn == 'Tangent': extendcommand = Path.Command('G1', { "X": p0.x, "Y": p0.y, "F": horizFeed }) results.append(extendcommand) else: PathLog.notice(" CURRENT_IN Perp") return results
def setup(self, obj): obj.Angle = 60 obj.Method = 2 if PathDressup.baseOp(obj).StartDepth is not None: obj.DressupStartDepth = PathDressup.baseOp(obj).StartDepth
def generateLeadInOutCurve(self, obj): global currLocation # pylint: disable=global-statement firstmove = Path.Command("G0", {"X": 0, "Y": 0, "Z": 0}) op = PathDressup.baseOp(obj.Base) currLocation.update(firstmove.Parameters) newpath = [] queue = [] action = 'start' prevCmd = '' layers = [] # Read in all commands for curCommand in obj.Base.Path.Commands: #PathLog.debug("CurCMD: {}".format(curCommand)) if curCommand.Name not in movecommands + rapidcommands: # Don't worry about non-move commands, just add to output newpath.append(curCommand) continue if curCommand.Name in rapidcommands: # We don't care about rapid moves prevCmd = curCommand currLocation.update(curCommand.Parameters) continue if curCommand.Name in movecommands: if prevCmd.Name in rapidcommands and curCommand.Name in movecommands and len( queue) > 0: # Layer changed: Save current layer cmds and prepare next layer layers.append(queue) queue = [] if obj.IncludeLayers and curCommand.z < currLocation[ 'Z'] and prevCmd.Name in movecommands: # Layer change within move cmds #PathLog.debug("Layer change in move: {}->{}".format(currLocation['Z'], curCommand.z)) layers.append(queue) queue = [] # Save all move commands queue.append(curCommand) currLocation.update(curCommand.Parameters) prevCmd = curCommand # Add last layer if len(queue) > 0: layers.append(queue) queue = [] # Go through each layer and add leadIn/Out idx = 0 for layer in layers: #PathLog.debug("Layer {}".format(idx)) if obj.LeadIn: temp = self.getLeadStart(obj, layer, action) newpath.extend(temp) for cmd in layer: #PathLog.debug("CurLoc: {}, NewCmd: {}".format(currLocation, cmd)) #if currLocation['X'] == cmd.x and currLocation['Y'] == cmd.y and currLocation['Z'] == cmd.z and cmd.Name in ['G1', 'G01']: #continue newpath.append(cmd) if obj.LeadOut: tmp = [] tmp.append(layer[-2]) tmp.append(layer[-1]) temp = self.getLeadEnd(obj, tmp, action) newpath.extend(temp) if not obj.KeepToolDown or idx == len(layers) - 1: extendcommand = Path.Command('G0', {"Z": op.ClearanceHeight.Value}) newpath.append(extendcommand) else: action = 'layer' idx += 1 commands = newpath return Path.Path(commands)
def getLeadStart(self, obj, queue, action): '''returns Lead In G-code.''' results = [] op = PathDressup.baseOp(obj.Base) tc = PathDressup.toolController(obj.Base) horizFeed = tc.HorizFeed.Value vertFeed = tc.VertFeed.Value toolnummer = tc.ToolNumber arcs_identical = False # Set the correct twist command if self.getDirectionOfPath(obj) == 'left': arcdir = "G3" else: arcdir = "G2" R = obj.Length.Value # Radius of roll or length if queue[1].Name == "G1": # line p0 = queue[0].Placement.Base p1 = queue[1].Placement.Base v = self.normalize(p1.sub(p0)) # PathLog.debug(" CURRENT_IN : P0 Z:{} p1 Z:{}".format(p0.z,p1.z)) else: p0 = queue[0].Placement.Base p1 = queue[1].Placement.Base v = self.normalize(p1.sub(p0)) # PathLog.debug(" CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format(p0.x,p0.y,p1.x,p1.y)) # Calculate offset vector (will be overwritten for arcs) if self.getDirectionOfPath(obj) == 'right': off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0) else: off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0) # Check if we enter at line or arc command if queue[1].Name in movecommands and queue[1].Name not in arccommands: # We have a line move vec = p1.sub(p0) vec_n = self.normalize(vec) vec_inv = self.invert(vec_n) vec_off = self.multiply(vec_inv, obj.ExtendLeadIn) #PathLog.debug("LineCMD: {}, Vxinv: {}, Vyinv: {}, Vxoff: {}, Vyoff: {}".format(queue[0].Name, vec_inv.x, vec_inv.y, vec_off.x, vec_off.y)) else: # We have an arc move # Calculate coordinates for middle of circle pij = copy.deepcopy(p0) pij.x += queue[1].Parameters['I'] pij.y += queue[1].Parameters['J'] # Check if lead in and operation go in same direction (usually for inner circles) if arcdir == queue[1].Name: arcs_identical = True # Calculate vector circle start -> circle middle vec_circ = pij.sub(p0) # Rotate vector to get direction for lead in if arcdir == "G2": vec_rot = self.rotate(vec_circ, 90) else: vec_rot = self.rotate(vec_circ, -90) # Normalize and invert vector vec_n = self.normalize(vec_rot) v = self.invert(vec_n) # Calculate offset of lead in if arcdir == "G3": off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0) else: off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0) # Multiply offset by LeadIn length vec_off = self.multiply(vec_n, obj.ExtendLeadIn) offsetvector = FreeCAD.Vector(v.x * R - vec_off.x, v.y * R - vec_off.y, 0) # IJ if obj.RadiusCenter == 'Radius': leadstart = (p0.add(off_v)).sub(offsetvector) # Rmode if arcs_identical: t = p0.sub(leadstart) t = p0.add(t) leadstart = t offsetvector = self.multiply(offsetvector, -1) else: leadstart = p0.add(off_v) # Dmode if action == 'start': #extendcommand = Path.Command('G0', {"X": 0.0, "Y": 0.0, "Z": op.ClearanceHeight.Value}) #results.append(extendcommand) extendcommand = Path.Command('G0', { "X": leadstart.x, "Y": leadstart.y, "Z": op.ClearanceHeight.Value }) results.append(extendcommand) extendcommand = Path.Command('G0', {"Z": op.SafeHeight.Value}) results.append(extendcommand) if action == 'layer': if not obj.KeepToolDown: extendcommand = Path.Command('G0', {"Z": op.SafeHeight.Value}) results.append(extendcommand) extendcommand = Path.Command('G0', { "X": leadstart.x, "Y": leadstart.y }) results.append(extendcommand) if not obj.RapidPlunge: extendcommand = Path.Command('G1', { "X": leadstart.x, "Y": leadstart.y, "Z": p1.z, "F": vertFeed }) else: extendcommand = Path.Command('G0', { "X": leadstart.x, "Y": leadstart.y, "Z": p1.z, }) results.append(extendcommand) if obj.UseMachineCRC: if self.getDirectionOfPath(obj) == 'right': results.append(Path.Command('G42', {'D': toolnummer})) else: results.append(Path.Command('G41', {'D': toolnummer})) if obj.StyleOn == 'Arc': arcmove = Path.Command( arcdir, { "X": p0.x + vec_off.x, "Y": p0.y + vec_off.y, "I": offsetvector.x + vec_off.x, "J": offsetvector.y + vec_off.y, "F": horizFeed }) # add G2/G3 move results.append(arcmove) if obj.ExtendLeadIn != 0: extendcommand = Path.Command('G1', { "X": p0.x, "Y": p0.y, "F": horizFeed }) results.append(extendcommand) elif obj.StyleOn == 'Tangent': extendcommand = Path.Command('G1', { "X": p0.x, "Y": p0.y, "F": horizFeed }) results.append(extendcommand) else: PathLog.debug(" CURRENT_IN Perp") currLocation.update(results[-1].Parameters) currLocation['Z'] = p1.z return results
def getSideOfPath(self, obj): op = PathDressup.baseOp(obj.Base) if hasattr(op, 'Side'): return op.Side return ''
def getLeadStart(self, obj, queue, action): """returns Lead In G-code.""" # Modified March 2022 by lcorley to support leadin extension results = [] op = PathDressup.baseOp(obj.Base) tc = PathDressup.toolController(obj.Base) horizFeed = tc.HorizFeed.Value vertFeed = tc.VertFeed.Value toolnummer = tc.ToolNumber arcs_identical = False # Set the correct twist command if self.getDirectionOfPath(obj) == "left": arcdir = "G3" else: arcdir = "G2" R = obj.Length.Value # Radius of roll or length if queue[1].Name == "G1": # line p0 = queue[0].Placement.Base p1 = queue[1].Placement.Base v = self.normalize(p1.sub(p0)) PathLog.debug(" CURRENT_IN Line : P0 Z:{} p1 Z:{}".format( p0.z, p1.z)) else: p0 = queue[0].Placement.Base p1 = queue[1].Placement.Base v = self.normalize(p1.sub(p0)) PathLog.debug( " CURRENT_IN ARC : P0 X:{} Y:{} P1 X:{} Y:{} ".format( p0.x, p0.y, p1.x, p1.y)) # Calculate offset vector (will be overwritten for arcs) if self.getDirectionOfPath(obj) == "right": off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0) else: off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0) # Check if we enter at line or arc command if queue[1].Name in movecommands and queue[1].Name not in arccommands: # We have a line move vec = p1.sub(p0) vec_n = self.normalize(vec) vec_inv = self.invert(vec_n) vec_off = self.multiply(vec_inv, obj.ExtendLeadIn) PathLog.debug( "LineCMD: {}, Vxinv: {}, Vyinv: {}, Vxoff: {}, Vyoff: {}". format(queue[0].Name, vec_inv.x, vec_inv.y, vec_off.x, vec_off.y)) else: # We have an arc move # Calculate coordinates for middle of circle pij = copy.deepcopy(p0) pij.x += queue[1].Parameters["I"] pij.y += queue[1].Parameters["J"] # Check if lead in and operation go in same direction (usually for inner circles) if arcdir == queue[1].Name: arcs_identical = True # Calculate vector circle start -> circle middle vec_circ = pij.sub(p0) # Rotate vector to get direction for lead in if arcdir == "G2": vec_rot = self.rotate(vec_circ, 90) else: vec_rot = self.rotate(vec_circ, -90) # Normalize and invert vector vec_n = self.normalize(vec_rot) v = self.invert(vec_n) # Calculate offset of lead in if arcdir == "G3": off_v = FreeCAD.Vector(-v.y * R, v.x * R, 0.0) else: off_v = FreeCAD.Vector(v.y * R, -v.x * R, 0.0) offsetvector = FreeCAD.Vector(v.x * R, v.y * R, 0) # IJ if obj.RadiusCenter == "Radius": leadstart = (p0.add(off_v)).sub(offsetvector) # Rmode if arcs_identical: t = p0.sub(leadstart) t = p0.add(t) leadstart = t offsetvector = self.multiply(offsetvector, -1) else: leadstart = p0.add(off_v) # Dmode # At this point leadstart is the beginning of the leadin arc # and offsetvector points from leadstart to the center of the leadin arc # so the offsetvector is a radius of the leadin arc at its start # The extend line should be tangent to the leadin arc at this point, or perpendicular to the radius if arcdir == "G2": tangentvec = self.rotate(offsetvector, -90) else: tangentvec = self.rotate(offsetvector, 90) # Normalize the tangent vector tangentvecNorm = self.normalize(tangentvec) # Multiply tangentvecNorm by LeadIn length leadlinevec = self.multiply(tangentvecNorm, obj.ExtendLeadIn) # leadlinevec provides the offset from the beginning of the lead arc to the beginning of the extend line extendstart = leadstart.add(leadlinevec) if action == "start": if obj.ExtendLeadIn != 0: # Rapid move to beginning of extend line extendcommand = Path.Command( "G0", { "X": extendstart.x, "Y": extendstart.y, "Z": op.ClearanceHeight.Value, }, ) else: # Rapid move to beginning of leadin arc extendcommand = Path.Command( "G0", { "X": extendstart.x, "Y": extendstart.y, "Z": op.ClearanceHeight.Value, }, ) results.append(extendcommand) extendcommand = Path.Command("G0", {"Z": op.SafeHeight.Value}) results.append(extendcommand) if action == "layer": if not obj.KeepToolDown: extendcommand = Path.Command("G0", {"Z": op.SafeHeight.Value}) results.append(extendcommand) extendcommand = Path.Command("G0", { "X": extendstart.x, "Y": extendstart.y }) results.append(extendcommand) if obj.RapidPlunge: extendcommand = Path.Command("G0", {"Z": p1.z}) else: extendcommand = Path.Command("G1", {"Z": p1.z, "F": vertFeed}) results.append(extendcommand) if obj.UseMachineCRC: if self.getDirectionOfPath(obj) == "right": results.append(Path.Command("G42", {"D": toolnummer})) else: results.append(Path.Command("G41", {"D": toolnummer})) if obj.StyleOn == "Arc": if obj.ExtendLeadIn != 0: # Insert move to beginning of leadin arc extendcommand = Path.Command("G1", { "X": leadstart.x, "Y": leadstart.y, "F": horizFeed }) results.append(extendcommand) arcmove = Path.Command( arcdir, { "X": p0.x, "Y": p0.y, "Z": p0.z, "I": offsetvector.x, "J": offsetvector.y, "K": offsetvector.z, "F": horizFeed, }, ) # add G2/G3 move results.append(arcmove) elif obj.StyleOn == "Tangent": extendcommand = Path.Command("G1", { "X": p0.x, "Y": p0.y, "F": horizFeed }) results.append(extendcommand) else: PathLog.debug(" CURRENT_IN Perp") currLocation.update(results[-1].Parameters) currLocation["Z"] = p1.z return results