def export(objectslist, filename, argstring): if not processArguments(argstring): return None global UNITS global POSTGCODE global G_FUNCTION_STORE global MACHINE_WORK_AXIS global MACHINE_LAST_POSITION global MACHINE_TRASL_ROT global STORED_COMPENSATED_OBJ global COMPENSATION_DIFF_STATUS global LBLIZE_STAUS Object_Kind = None Feed_Rapid = False Feed = 0 Spindle_RPM = 0 Spindle_Active = False ToolId = "" Compensation = "0" params = [ 'X', 'Y', 'Z', 'A', 'B', 'C', 'I', 'J', 'K', 'F', 'H', 'S', 'T', 'Q', 'R', 'L' ] for obj in objectslist: if not hasattr(obj, "Path"): print( "the object " + obj.Name + " is not a path. Please select only path and Compounds." ) return POSTGCODE.append(HEIDEN_Begin(objectslist)) #add header for obj in objectslist: Cmd_Count = 0 # command line number LBLIZE_STAUS = False # useful to get idea of object kind if isinstance (obj.Proxy, PathScripts.PathToolController.ToolController): Object_Kind = "TOOL" # like we go to change tool position MACHINE_LAST_POSITION['X'] = 99999 MACHINE_LAST_POSITION['Y'] = 99999 MACHINE_LAST_POSITION['Z'] = 99999 elif isinstance (obj.Proxy, PathScripts.PathProfileEdges.ObjectProfile): Object_Kind = "PROFILE" if LBLIZE_ACTIVE: LBLIZE_STAUS = True elif isinstance (obj.Proxy, PathScripts.PathMillFace.ObjectFace): Object_Kind = "FACE" if LBLIZE_ACTIVE: LBLIZE_STAUS = True elif isinstance (obj.Proxy, PathScripts.PathHelix.ObjectHelix): Object_Kind = "HELIX" # If used compensated path, store, recompute and diff when asked if hasattr(obj, 'UseComp') and SOLVE_COMPENSATION_ACTIVE: if obj.UseComp: if hasattr(obj.Path, 'Commands') and Object_Kind == "PROFILE": # Take a copy of compensated path STORED_COMPENSATED_OBJ = obj.Path.Commands # Find mill compensation if hasattr(obj, 'Side') and hasattr(obj, 'Direction'): if obj.Side == "Outside" and obj.Direction == "CW": Compensation = "L" elif obj.Side == "Outside" and obj.Direction == "CCW": Compensation = "R" elif obj.Side != "Outside" and obj.Direction == "CW": Compensation = "R" else: Compensation = "L" # set obj.UseComp to false and recompute() to get uncompensated path obj.UseComp = False obj.recompute() # small edges could be skipped and movements joints can add edges NameStr = "" if hasattr(obj, 'Label'): NameStr = str(obj.Label) if len(obj.Path.Commands) != len(STORED_COMPENSATED_OBJ): # not same number of edges obj.UseComp = True obj.recompute() POSTGCODE.append("; MISSING EDGES UNABLE TO GET COMPENSATION") if not SKIP_WARNS: ( PostUtils.editor( "--solve-comp command ACTIVE\n\n" + "UNABLE to solve " + NameStr + " compensation\n\n" + "Some edges are missing\n" + "try to change Join Type to Miter or Square\n" + "try to use a smaller Tool Diameter\n" + "Internal Path could have too small corners\n\n" + "use --no-warns to not prompt this message" ) ) else: if not SKIP_WARNS: ( PostUtils.editor( "--solve-comp command ACTIVE\n\n" + "BE CAREFUL with solved " + NameStr + " compensation\n\n" + "USE AT YOUR OWN RISK\n" + "Simulate it before use\n" + "Offset Extra ignored use DR+ on TOOL CALL\n" + "Path could be different and/or give tool radius errors\n\n" + "use --no-warns to not prompt this message" ) ) # we can try to solve compensation POSTGCODE.append("; COMPENSATION ACTIVE") COMPENSATION_DIFF_STATUS[0] = True for c in obj.Path.Commands: Cmd_Count += 1 outstring = [] command = c.Name if command != 'G0': command = command.replace('G0','G') # normalize: G01 -> G1 Feed_Rapid = False else: Feed_Rapid = True for param in params: if param in c.Parameters: if param == 'F': Feed = c.Parameters['F'] elif param == 'S': Spindle_RPM = c.Parameters['S'] # Could be deleted if tool it's OK elif param == 'T': ToolId = c.Parameters['T'] # Could be deleted if tool it's OK if command == 'G90': G_FUNCTION_STORE['G90'] = True G_FUNCTION_STORE['G91'] = False if command == 'G91': G_FUNCTION_STORE['G91'] = True G_FUNCTION_STORE['G90'] = False if command == 'G98': G_FUNCTION_STORE['G98'] = True G_FUNCTION_STORE['G99'] = False if command == 'G99': G_FUNCTION_STORE['G99'] = True G_FUNCTION_STORE['G98'] = False # Rapid movement if command == 'G0': Spindle_Status = "" if Spindle_Active == False: # At first rapid movement we turn on spindle Spindle_Status += str(MACHINE_SPINDLE_DIRECTION) # Activate spindle Spindle_Active = True else: # At last rapid movement we turn off spindle if Cmd_Count == len(obj.Path.Commands): Spindle_Status += "5" # Deactivate spindle Spindle_Active = False else: Spindle_Status += "" # Spindle still active parsedElem = HEIDEN_Line( c.Parameters, Compensation, Feed, True, Spindle_Status, Cmd_Count ) if parsedElem != None: POSTGCODE.append(parsedElem) # Linear movement if command == 'G1': parsedElem = HEIDEN_Line( c.Parameters, Compensation, Feed, False, "", Cmd_Count ) if parsedElem != None: POSTGCODE.append(parsedElem) # Arc movement if command == 'G2' or command == 'G3': parsedElem = HEIDEN_Arc( c.Parameters, command, Compensation, Feed, False, "", Cmd_Count ) if parsedElem != None: POSTGCODE.extend(parsedElem) if command == 'G80': #Reset Canned Cycles G_FUNCTION_STORE['G81'] = False G_FUNCTION_STORE['G82'] = False G_FUNCTION_STORE['G83'] = False # Drilling, Dwell Drilling, Peck Drilling if command == 'G81' or command == 'G82' or command == 'G83': parsedElem = HEIDEN_Drill( obj, c.Parameters, command, Feed ) if parsedElem != None: POSTGCODE.extend(parsedElem) # Tool change if command == 'M6': parsedElem = HEIDEN_ToolCall(obj) if parsedElem != None: POSTGCODE.append(parsedElem) if COMPENSATION_DIFF_STATUS[0]: #Restore the compensation if removed obj.UseComp = True obj.recompute() COMPENSATION_DIFF_STATUS[0] = False if LBLIZE_STAUS: HEIDEN_LBL_Replace() LBLIZE_STAUS = False if LBLIZE_ACTIVE: if not SKIP_WARNS: ( PostUtils.editor( "--solve-lbl command ACTIVE\n\n" + "BE CAREFUL with LBL replacements\n\n" + "USE AT YOUR OWN RISK\n" + "Simulate it before use\n" + "Path could be different and/or give errors\n\n" + "use --no-warns to not prompt this message" ) ) POSTGCODE.append(HEIDEN_End(objectslist)) #add footer Program_Out = HEIDEN_Numberize(POSTGCODE) #add line number if SHOW_EDITOR: PostUtils.editor(Program_Out) gfile = pythonopen(filename, "w") gfile.write(Program_Out) gfile.close()
def export(objectslist, filename, argstring): global UNITS global linenr global ABSOLUTE_CIRCLE_CENTER global USE_RADIUS_IF_POSSIBLE global RADIUS_COMMENT linenr = STARTLINENR lastX = 0 lastY = 0 lastZ = 0 params = [ 'X', 'Y', 'Z', 'A', 'B', 'I', 'J', 'F', 'H', 'S', 'T', 'Q', 'R', 'L' ] # Using XY plane most of the time so skipping K modalParamsDict = dict() for mp in MODALPARAMS: modalParamsDict[mp] = None for obj in objectslist: if not hasattr(obj, "Path"): print("the object " + obj.Name + " is not a path. Please select only path and Compounds.") return myMachine = None for pathobj in objectslist: if hasattr(pathobj, "MachineName"): myMachine = pathobj.MachineName if hasattr(pathobj, "MachineUnits"): if pathobj.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" if myMachine is None: print("philips_post: No machine found in this selection") gcode = '' gcode += mkHeader(objectslist) gcode += linenumberify(GCODE_HEADER) if UNITS_INCLUDED: gcode += linenumberify(mapGCode(UNITS)) lastcommand = None for obj in objectslist: if hasattr(obj, 'Comment'): gcode += linenumberify('(' + obj.Comment + ')') for c in obj.Path.Commands: outstring = [] command = c.Name if command != 'G0': command = command.replace('G0', 'G') # normalize: G01 -> G1 if (command != UNITS or UNITS_INCLUDED): if command[0] == '(': command = PostUtils.fcoms(command, COMMENT) # the mapping is done for output only! For internal things we # still use the old value. mappedCommand = mapGCode(command) if not MODAL or command != lastcommand: outstring.append(mappedCommand) # if MODAL == True: # #\better: append iff MODAL == False # if command == lastcommand: # outstring.pop(0) if c.Parameters >= 1: for param in params: # test print("param: " + param + ", command: " + command) if param in c.Parameters: if (param in MODALPARAMS) and ( modalParamsDict[str(param)] == c.Parameters[str(param)]): # do nothing or append white space outstring.append(' ') elif param == 'F': feed = c.Parameters['F'] if SUPPRESS_ZERO_FEED and feed == 0: pass else: outstring.append(param + PostUtils.fmt( feed, FEED_DECIMALS, UNITS)) elif param == 'H': outstring.append(param + str(int(c.Parameters['H']))) elif param == 'S': # rpm is unitless-therefore I had to 'fake it # out' by using metric units which don't get # converted from entered value outstring.append( param + PostUtils.fmt(c.Parameters['S'], SPINDLE_DECIMALS, 'G21')) elif param == 'T': outstring.append(param + str(int(c.Parameters['T']))) elif param == 'I' and (command == 'G2' or command == 'G3'): #test print("param = 'I'") # this is the special case for circular paths, # where relative coordinates have to be changed # to absolute i = c.Parameters['I'] # calculate the radius r j = c.Parameters['J'] r = math.sqrt(i**2 + j**2) if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): outstring.append( 'R' + PostUtils.fmt(r, AXIS_DECIMALS, UNITS)) else: if RADIUS_COMMENT: outstring.append('(R' + PostUtils.fmt( r, AXIS_DECIMALS, UNITS) + ')') if ABSOLUTE_CIRCLE_CENTER: i += lastX outstring.append( param + PostUtils.fmt(i, AXIS_DECIMALS, UNITS)) elif param == 'J' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, # where incremental center has to be changed to # absolute center i = c.Parameters['I'] j = c.Parameters['J'] if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): # R is handled with the I parameter, here: # do nothing at all, keep the structure as # with I command pass else: if ABSOLUTE_CIRCLE_CENTER: j += lastY if SWAP_Y_Z: # we have to swap j and k as well outstring.append('K' + PostUtils.fmt( j, AXIS_DECIMALS, UNITS)) else: outstring.append(param + PostUtils.fmt( j, AXIS_DECIMALS, UNITS)) elif param == 'K' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, # where incremental center has to be changed to # absolute center outstring.append( '(' + param + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS) + ')') z = c.Parameters['Z'] k = c.Parameters['K'] if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): # R is handled with the I parameter, here: # do nothing at all, keep the structure as # with I command pass else: if ABSOLUTE_CIRCLE_CENTER: k += lastZ if SWAP_Y_Z: # we have to swap j and k as well outstring.append( 'J' + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) else: outstring.append( param + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) elif param == 'Y' and SWAP_Y_Z: outstring.append('Z' + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) elif param == 'Z' and SWAP_Y_Z: outstring.append('Y' + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) else: # To Do: suppress unknown commands, if this is done here, all X parameters are suppressed # this is an unknown command, don't create GCode for it # print("parameter " + param + " for command " + command + " ignored") outstring.append(param + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) if param in MODALPARAMS: modalParamsDict[str( param)] = c.Parameters[param] # save the last X, Y, Z values if 'X' in c.Parameters: lastX = c.Parameters['X'] if 'Y' in c.Parameters: lastY = c.Parameters['Y'] if 'Z' in c.Parameters: lastZ = c.Parameters['Z'] outstr = '' for w in outstring: outstr += w + COMMAND_SPACE outstr = outstr.replace(']', '') outstr = outstr.replace('[', '') outstr = outstr.replace("'", '') outstr = outstr.replace(",", '.') if LINENUMBERS: gcode += "N" + str(linenr) + " " linenr += LINENUMBER_INCREMENT gcode += outstr + '\n' lastcommand = c.Name gcode = gcode.replace("_", "-") gcode += linenumberify(GCODE_FOOTER) if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename, "wb") gfile.write(gcode) gfile.close()
def export(selection, filename, argstring): global linenr linenr = STARTLINENR lastX = 0 lastY = 0 lastZ = 0 params = [ 'X', 'Y', 'Z', 'A', 'B', 'I', 'J', 'F', 'H', 'S', 'T', 'Q', 'R', 'L' ] #Using XY plane most of the time so skipping K modalParamsDict = dict() for mp in MODALPARAMS: modalParamsDict[mp] = None for obj in selection: if not hasattr(obj, "Path"): print "the object " + obj.Name + " is not a path. Please select only path and Compounds." return myMachine = None for pathobj in selection: if hasattr(pathobj, "MachineName"): myMachine = pathobj.MachineName if hasattr(pathobj, "MachineUnits"): if pathobj.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" if myMachine is None: print "No machine found in this selection" gcode = '' gcode += mkHeader(selection) gcode += linenumberify(GCODE_HEADER) if UNITS_INCLUDED: gcode += linenumberify(mapGCode(UNITS)) lastcommand = None gobjects = [] for g in selection[0].Group: if g.Name <> 'Machine': #filtering out gcode home position from Machine object gobjects.append(g) for obj in gobjects: if hasattr(obj, 'Comment'): gcode += linenumberify('(' + obj.Comment + ')') for c in obj.Path.Commands: outstring = [] command = c.Name if (command != UNITS or UNITS_INCLUDED): if command[0] == '(': command = PostUtils.fcoms(command, COMMENT) mappedCommand = mapGCode( command ) # the mapping is done for output only! For internal things we still use the old value. if not MODAL or command != lastcommand: outstring.append(mappedCommand) # if MODAL == True: ) # #\better: append iff MODAL == False ) # if command == lastcommand: ) # outstring.pop(0!#\ ) if c.Parameters >= 1: for param in params: if param in c.Parameters: if (param in MODALPARAMS) and ( modalParamsDict[str(param)] == c.Parameters[str(param)]): # do nothing or append white space outstring.append(' ') elif param == 'F': outstring.append(param + PostUtils.fmt( c.Parameters['F'], FEED_DECIMALS, UNITS)) elif param == 'H': outstring.append(param + str(int(c.Parameters['H']))) elif param == 'S': outstring.append( param + PostUtils.fmt(c.Parameters['S'], SPINDLE_DECIMALS, 'G21') ) #rpm is unitless-therefore I had to 'fake it out' by using metric units which don't get converted from entered value elif param == 'T': outstring.append(param + str(int(c.Parameters['T']))) elif param == 'I' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, where relative coordinates have to be changed to absolute i = c.Parameters['I'] # calculate the radius r j = c.Parameters['J'] r = math.sqrt(i**2 + j**2) if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): outstring.append( 'R' + PostUtils.fmt(r, AXIS_DECIMALS, UNITS)) else: if RADIUS_COMMENT: outstring.append('(R' + PostUtils.fmt( r, AXIS_DECIMALS, UNITS) + ')') if ABSOLUTE_CIRCLE_CENTER: i += lastX outstring.append( param + PostUtils.fmt(i, AXIS_DECIMALS, UNITS)) elif param == 'J' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, where incremental center has to be changed to absolute center i = c.Parameters['I'] j = c.Parameters['J'] if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): # R is handled with the I parameter, here: do nothing at all, keep the structure as with I command pass else: if ABSOLUTE_CIRCLE_CENTER: j += lastY if SWAP_Y_Z: # we have to swap j and k as well outstring.append('K' + PostUtils.fmt( j, AXIS_DECIMALS, UNITS)) else: outstring.append(param + PostUtils.fmt( j, AXIS_DECIMALS, UNITS)) elif param == 'K' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, where incremental center has to be changed to absolute center outstring.append( '(' + param + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS) + ')') z = c.Parameters['Z'] k = c.Parameters['K'] if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): # R is handled with the I parameter, here: do nothing at all, keep the structure as with I command pass else: if ABSOLUTE_CIRCLE_CENTER: k += lastZ if SWAP_Y_Z: # we have to swap j and k as well outstring.append( 'J' + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) else: outstring.append( param + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) elif param == 'Y' and SWAP_Y_Z: outstring.append('Z' + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) elif param == 'Z' and SWAP_Y_Z: outstring.append('Y' + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) else: outstring.append(param + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) if param in MODALPARAMS: modalParamsDict[str( param)] = c.Parameters[param] # save the last X, Y, Z values if 'X' in c.Parameters: lastX = c.Parameters['X'] if 'Y' in c.Parameters: lastY = c.Parameters['Y'] if 'Z' in c.Parameters: lastZ = c.Parameters['Z'] outstr = str(outstring) outstr = outstr.replace(']', '') outstr = outstr.replace('[', '') outstr = outstr.replace("'", '') outstr = outstr.replace(",", '') if LINENUMBERS: gcode += "N" + str(linenr) + " " linenr += LINENUMBER_INCREMENT gcode += outstr + '\n' lastcommand = c.Name gcode += linenumberify(GCODE_FOOTER) if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename, "wb") gfile.write(gcode) gfile.close()
def export(objectslist, filename, argstring): global UNITS global linenr global ABSOLUTE_CIRCLE_CENTER global USE_RADIUS_IF_POSSIBLE global RADIUS_COMMENT linenr = STARTLINENR lastX = 0 lastY = 0 lastZ = 0 params = ['X', 'Y', 'Z', 'A', 'B', 'I', 'J', 'F', 'H', 'S', 'T', 'Q', 'R', 'L'] # Using XY plane most of the time so skipping K modalParamsDict = dict() for mp in MODALPARAMS: modalParamsDict[mp] = None for obj in objectslist: if not hasattr(obj, "Path"): print("the object " + obj.Name + " is not a path. Please select only path and Compounds.") return myMachine = None for pathobj in objectslist: if hasattr(pathobj, "MachineName"): myMachine = pathobj.MachineName if hasattr(pathobj, "MachineUnits"): if pathobj.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" if myMachine is None: print("philips_post: No machine found in this selection") gcode = '' gcode += mkHeader(objectslist) gcode += linenumberify(GCODE_HEADER) if UNITS_INCLUDED: gcode += linenumberify(mapGCode(UNITS)) lastcommand = None for obj in objectslist: if hasattr(obj, 'Comment'): gcode += linenumberify('(' + obj.Comment + ')') for c in obj.Path.Commands: outstring = [] command = c.Name if command != 'G0': command = command.replace('G0','G') # normalize: G01 -> G1 if (command != UNITS or UNITS_INCLUDED): if command[0] == '(': command = PostUtils.fcoms(command, COMMENT) # the mapping is done for output only! For internal things we # still use the old value. mappedCommand = mapGCode(command) if not MODAL or command != lastcommand: outstring.append(mappedCommand) # if MODAL == True: # #\better: append iff MODAL == False # if command == lastcommand: # outstring.pop(0) if c.Parameters >= 1: for param in params: # test print("param: " + param + ", command: " + command) if param in c.Parameters: if (param in MODALPARAMS) and (modalParamsDict[str(param)] == c.Parameters[str(param)]): # do nothing or append white space outstring.append(' ') elif param == 'F': feed = c.Parameters['F'] if SUPPRESS_ZERO_FEED and feed == 0: pass else: outstring.append( param + PostUtils.fmt(feed, FEED_DECIMALS, UNITS)) elif param == 'H': outstring.append( param + str(int(c.Parameters['H']))) elif param == 'S': # rpm is unitless-therefore I had to 'fake it # out' by using metric units which don't get # converted from entered value outstring.append( param + PostUtils.fmt(c.Parameters['S'], SPINDLE_DECIMALS, 'G21')) elif param == 'T': outstring.append( param + str(int(c.Parameters['T']))) elif param == 'I' and (command == 'G2' or command == 'G3'): #test print("param = 'I'") # this is the special case for circular paths, # where relative coordinates have to be changed # to absolute i = c.Parameters['I'] # calculate the radius r j = c.Parameters['J'] r = math.sqrt(i**2 + j**2) if USE_RADIUS_IF_POSSIBLE and angleUnder180(command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): outstring.append( 'R' + PostUtils.fmt(r, AXIS_DECIMALS, UNITS)) else: if RADIUS_COMMENT: outstring.append( '(R' + PostUtils.fmt(r, AXIS_DECIMALS, UNITS) + ')') if ABSOLUTE_CIRCLE_CENTER: i += lastX outstring.append( param + PostUtils.fmt(i, AXIS_DECIMALS, UNITS)) elif param == 'J' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, # where incremental center has to be changed to # absolute center i = c.Parameters['I'] j = c.Parameters['J'] if USE_RADIUS_IF_POSSIBLE and angleUnder180(command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): # R is handled with the I parameter, here: # do nothing at all, keep the structure as # with I command pass else: if ABSOLUTE_CIRCLE_CENTER: j += lastY if SWAP_Y_Z: # we have to swap j and k as well outstring.append( 'K' + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) else: outstring.append( param + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) elif param == 'K' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, # where incremental center has to be changed to # absolute center outstring.append( '(' + param + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS) + ')') z = c.Parameters['Z'] k = c.Parameters['K'] if USE_RADIUS_IF_POSSIBLE and angleUnder180(command, lastX, lastY, c.Parameters['X'], c.Parameters['Y'], i, j): # R is handled with the I parameter, here: # do nothing at all, keep the structure as # with I command pass else: if ABSOLUTE_CIRCLE_CENTER: k += lastZ if SWAP_Y_Z: # we have to swap j and k as well outstring.append( 'J' + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) else: outstring.append( param + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) elif param == 'Y' and SWAP_Y_Z: outstring.append( 'Z' + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS)) elif param == 'Z' and SWAP_Y_Z: outstring.append( 'Y' + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS)) else: # To Do: suppress unknown commands, if this is done here, all X parameters are suppressed # this is an unknown command, don't create GCode for it # print("parameter " + param + " for command " + command + " ignored") outstring.append( param + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS)) if param in MODALPARAMS: modalParamsDict[str(param)] = c.Parameters[ param] # save the last X, Y, Z values if 'X' in c.Parameters: lastX = c.Parameters['X'] if 'Y' in c.Parameters: lastY = c.Parameters['Y'] if 'Z' in c.Parameters: lastZ = c.Parameters['Z'] outstr = '' for w in outstring: outstr += w + COMMAND_SPACE outstr = outstr.replace(']', '') outstr = outstr.replace('[', '') outstr = outstr.replace("'", '') outstr = outstr.replace(",", '.') if LINENUMBERS: gcode += "N" + str(linenr) + " " linenr += LINENUMBER_INCREMENT gcode += outstr + '\n' lastcommand = c.Name gcode = gcode.replace("_","-") gcode += linenumberify(GCODE_FOOTER) if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename, "w") gfile.write(gcode) gfile.close()
def export(objectslist, filename, argstring): global UNITS global linenr linenr = STARTLINENR lastX = 0 lastY = 0 lastZ = 0 params = [ "X", "Y", "Z", "A", "B", "I", "J", "F", "H", "S", "T", "Q", "R", "L", ] # Using XY plane most of the time so skipping K modalParamsDict = dict() for mp in MODALPARAMS: modalParamsDict[mp] = None for obj in objectslist: if not hasattr(obj, "Path"): print("the object " + obj.Name + " is not a path. Please select only path and Compounds.") return myMachine = None for pathobj in objectslist: if hasattr(pathobj, "MachineName"): myMachine = pathobj.MachineName if hasattr(pathobj, "MachineUnits"): if pathobj.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" if myMachine is None: print("philips_post: No machine found in this selection") gcode = "" gcode += mkHeader(objectslist) gcode += linenumberify(GCODE_HEADER) if UNITS_INCLUDED: gcode += linenumberify(mapGCode(UNITS)) lastcommand = None for obj in objectslist: if hasattr(obj, "Comment"): gcode += linenumberify("(" + obj.Comment + ")") for c in obj.Path.Commands: outstring = [] command = c.Name if command != "G0": command = command.replace("G0", "G") # normalize: G01 -> G1 if command != UNITS or UNITS_INCLUDED: if command[0] == "(": command = PostUtils.fcoms(command, COMMENT) # the mapping is done for output only! For internal things we # still use the old value. mappedCommand = mapGCode(command) if not MODAL or command != lastcommand: outstring.append(mappedCommand) # if MODAL: # #\better: append iff MODAL == False # if command == lastcommand: # outstring.pop(0) if len(c.Parameters) >= 1: for param in params: # test print("param: " + param + ", command: " + command) if param in c.Parameters: if (param in MODALPARAMS) and ( modalParamsDict[str(param)] == c.Parameters[str(param)]): # do nothing or append white space outstring.append(" ") elif param == "F": feed = c.Parameters["F"] if SUPPRESS_ZERO_FEED and feed == 0: pass else: outstring.append(param + PostUtils.fmt( feed, FEED_DECIMALS, UNITS)) elif param == "H": outstring.append(param + str(int(c.Parameters["H"]))) elif param == "S": # rpm is unitless-therefore I had to 'fake it # out' by using metric units which don't get # converted from entered value outstring.append( param + PostUtils.fmt(c.Parameters["S"], SPINDLE_DECIMALS, "G21")) elif param == "T": outstring.append(param + str(int(c.Parameters["T"]))) elif param == "I" and (command == "G2" or command == "G3"): # test print("param = 'I'") # this is the special case for circular paths, # where relative coordinates have to be changed # to absolute i = c.Parameters["I"] # calculate the radius r j = c.Parameters["J"] r = math.sqrt(i**2 + j**2) if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters["X"], c.Parameters["Y"], i, j, ): outstring.append( "R" + PostUtils.fmt(r, AXIS_DECIMALS, UNITS)) else: if RADIUS_COMMENT: outstring.append("(R" + PostUtils.fmt( r, AXIS_DECIMALS, UNITS) + ")") if ABSOLUTE_CIRCLE_CENTER: i += lastX outstring.append( param + PostUtils.fmt(i, AXIS_DECIMALS, UNITS)) elif param == "J" and (command == "G2" or command == "G3"): # this is the special case for circular paths, # where incremental center has to be changed to # absolute center i = c.Parameters["I"] j = c.Parameters["J"] if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters["X"], c.Parameters["Y"], i, j, ): # R is handled with the I parameter, here: # do nothing at all, keep the structure as # with I command pass else: if ABSOLUTE_CIRCLE_CENTER: j += lastY if SWAP_Y_Z: # we have to swap j and k as well outstring.append("K" + PostUtils.fmt( j, AXIS_DECIMALS, UNITS)) else: outstring.append(param + PostUtils.fmt( j, AXIS_DECIMALS, UNITS)) elif param == "K" and (command == "G2" or command == "G3"): # this is the special case for circular paths, # where incremental center has to be changed to # absolute center outstring.append( "(" + param + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS) + ")") z = c.Parameters["Z"] k = c.Parameters["K"] if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters["X"], c.Parameters["Y"], i, j, ): # R is handled with the I parameter, here: # do nothing at all, keep the structure as # with I command pass else: if ABSOLUTE_CIRCLE_CENTER: k += lastZ if SWAP_Y_Z: # we have to swap j and k as well outstring.append( "J" + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) else: outstring.append( param + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) elif param == "Y" and SWAP_Y_Z: outstring.append("Z" + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) elif param == "Z" and SWAP_Y_Z: outstring.append("Y" + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) else: # To Do: suppress unknown commands, if this is done here, all X parameters are suppressed # this is an unknown command, don't create GCode for it # print("parameter " + param + " for command " + command + " ignored") outstring.append(param + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) if param in MODALPARAMS: modalParamsDict[str( param)] = c.Parameters[param] # save the last X, Y, Z values if "X" in c.Parameters: lastX = c.Parameters["X"] if "Y" in c.Parameters: lastY = c.Parameters["Y"] if "Z" in c.Parameters: lastZ = c.Parameters["Z"] outstr = "" for w in outstring: outstr += w + COMMAND_SPACE outstr = outstr.replace("]", "") outstr = outstr.replace("[", "") outstr = outstr.replace("'", "") outstr = outstr.replace(",", ".") if LINENUMBERS: gcode += "N" + str(linenr) + " " linenr += LINENUMBER_INCREMENT gcode += outstr + "\n" lastcommand = c.Name gcode = gcode.replace("_", "-") gcode += linenumberify(GCODE_FOOTER) if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename, "w") gfile.write(gcode) gfile.close()
def export(selection, filename, argstring): params = [ 'X', 'Y', 'Z', 'A', 'B', 'I', 'J', 'F', 'H', 'S', 'T', 'Q', 'R', 'L' ] #Using XY plane most of the time so skipping K for obj in selection: if not hasattr(obj, "Path"): print("the object " + obj.Name + " is not a path. Please select only path and Compounds.") return myMachine = None for pathobj in selection: if hasattr(pathobj, "MachineName"): myMachine = pathobj.MachineName if hasattr(pathobj, "MachineUnits"): if pathobj.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" if myMachine is None: print("No machine found in this selection") gcode = '' gcode += HEADER % (FreeCAD.ActiveDocument.FileName) gcode += SAFETYBLOCK gcode += UNITS + '\n' lastcommand = None gcode += COMMENT + selection[0].Description + '\n' gobjects = [] for g in selection[0].Group: gobjects.append(g) for obj in gobjects: for c in obj.Path.Commands: outstring = [] command = c.Name if command[0] == '(': command = PostUtils.fcoms(command, COMMENT) outstring.append(command) if MODAL == True: if command == lastcommand: outstring.pop(0) if c.Parameters >= 1: for param in params: if param in c.Parameters: if param == 'F': outstring.append(param + PostUtils.fmt( c.Parameters['F'], FEED_DECIMALS, UNITS)) elif param == 'H': outstring.append(param + str(int(c.Parameters['H']))) elif param == 'S': outstring.append( param + PostUtils.fmt(c.Parameters['S'], SPINDLE_DECIMALS, 'G21') ) #rpm is unitless-therefore I had to 'fake it out' by using metric units which don't get converted from entered value elif param == 'T': outstring.append(param + str(int(c.Parameters['T']))) else: outstring.append(param + PostUtils.fmt( c.Parameters[param], AXIS_DECIMALS, UNITS)) outstr = str(outstring) outstr = outstr.replace('[', '') outstr = outstr.replace(']', '') outstr = outstr.replace("'", '') outstr = outstr.replace(",", '') gcode += outstr + '\n' lastcommand = c.Name gcode += TOOLRETURN gcode += SAFETYBLOCK gcode += FOOTER if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename, "wb") gfile.write(gcode) gfile.close()
def export(selection, filename, argstring): global linenr linenr = STARTLINENR lastX = 0 lastY = 0 lastZ = 0 params = [ "X", "Y", "Z", "A", "B", "I", "J", "F", "H", "S", "T", "Q", "R", "L", ] # Using XY plane most of the time so skipping K modalParamsDict = dict() for mp in MODALPARAMS: modalParamsDict[mp] = None for obj in selection: if not hasattr(obj, "Path"): print "the object " + obj.Name + " is not a path. Please select only path and Compounds." return myMachine = None for pathobj in selection: if hasattr(pathobj, "MachineName"): myMachine = pathobj.MachineName if hasattr(pathobj, "MachineUnits"): if pathobj.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" if myMachine is None: print "No machine found in this selection" gcode = "" gcode += mkHeader(selection) gcode += linenumberify(GCODE_HEADER) if UNITS_INCLUDED: gcode += linenumberify(mapGCode(UNITS)) lastcommand = None gobjects = [] for g in selection[0].Group: gobjects.append(g) for obj in gobjects: if hasattr(obj, "GComment"): gcode += linenumberify("(" + obj.GComment + ")") for c in obj.Path.Commands: outstring = [] command = c.Name if command != UNITS or UNITS_INCLUDED: if command[0] == "(": command = PostUtils.fcoms(command, COMMENT) mappedCommand = mapGCode( command ) # the mapping is done for output only! For internal things we still use the old value. if not MODAL or command != lastcommand: outstring.append(mappedCommand) # if MODAL == True: ) # #\better: append iff MODAL == False ) # if command == lastcommand: ) # outstring.pop(0!#\ ) if c.Parameters >= 1: for param in params: if param in c.Parameters: if (param in MODALPARAMS) and (modalParamsDict[str(param)] == c.Parameters[str(param)]): # do nothing or append white space outstring.append(" ") elif param == "F": outstring.append(param + PostUtils.fmt(c.Parameters["F"], FEED_DECIMALS, UNITS)) elif param == "H": outstring.append(param + str(int(c.Parameters["H"]))) elif param == "S": outstring.append( param + PostUtils.fmt(c.Parameters["S"], SPINDLE_DECIMALS, "G21") ) # rpm is unitless-therefore I had to 'fake it out' by using metric units which don't get converted from entered value elif param == "T": outstring.append(param + str(int(c.Parameters["T"]))) elif param == "I" and (command == "G2" or command == "G3"): # this is the special case for circular paths, where relative coordinates have to be changed to absolute i = c.Parameters["I"] # calculate the radius r j = c.Parameters["J"] r = math.sqrt(i ** 2 + j ** 2) if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters["X"], c.Parameters["Y"], i, j ): outstring.append("R" + PostUtils.fmt(r, AXIS_DECIMALS, UNITS)) else: if RADIUS_COMMENT: outstring.append("(R" + PostUtils.fmt(r, AXIS_DECIMALS, UNITS) + ")") if ABSOLUTE_CIRCLE_CENTER: i += lastX outstring.append(param + PostUtils.fmt(i, AXIS_DECIMALS, UNITS)) elif param == "J" and (command == "G2" or command == "G3"): # this is the special case for circular paths, where incremental center has to be changed to absolute center i = c.Parameters["I"] j = c.Parameters["J"] if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters["X"], c.Parameters["Y"], i, j ): # R is handled with the I parameter, here: do nothing at all, keep the structure as with I command pass else: if ABSOLUTE_CIRCLE_CENTER: j += lastY if SWAP_Y_Z: # we have to swap j and k as well outstring.append("K" + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) else: outstring.append(param + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) elif param == "K" and (command == "G2" or command == "G3"): # this is the special case for circular paths, where incremental center has to be changed to absolute center outstring.append( "(" + param + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS) + ")" ) z = c.Parameters["Z"] k = c.Parameters["K"] if USE_RADIUS_IF_POSSIBLE and angleUnder180( command, lastX, lastY, c.Parameters["X"], c.Parameters["Y"], i, j ): # R is handled with the I parameter, here: do nothing at all, keep the structure as with I command pass else: if ABSOLUTE_CIRCLE_CENTER: k += lastZ if SWAP_Y_Z: # we have to swap j and k as well outstring.append("J" + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) else: outstring.append(param + PostUtils.fmt(j, AXIS_DECIMALS, UNITS)) elif param == "Y" and SWAP_Y_Z: outstring.append("Z" + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS)) elif param == "Z" and SWAP_Y_Z: outstring.append("Y" + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS)) else: outstring.append(param + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS)) if param in MODALPARAMS: modalParamsDict[str(param)] = c.Parameters[param] # save the last X, Y, Z values if "X" in c.Parameters: lastX = c.Parameters["X"] if "Y" in c.Parameters: lastY = c.Parameters["Y"] if "Z" in c.Parameters: lastZ = c.Parameters["Z"] outstr = str(outstring) outstr = outstr.replace("]", "") outstr = outstr.replace("[", "") outstr = outstr.replace("'", "") outstr = outstr.replace(",", "") if LINENUMBERS: gcode += "N" + str(linenr) + " " linenr += LINENUMBER_INCREMENT gcode += outstr + "\n" lastcommand = c.Name gcode += linenumberify(GCODE_FOOTER) if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename, "wb") gfile.write(gcode) gfile.close()
def export(selection, filename, argstring): params = [ "X", "Y", "Z", "A", "B", "I", "J", "F", "H", "S", "T", "Q", "R", "L", ] # Using XY plane most of the time so skipping K for obj in selection: if not hasattr(obj, "Path"): print "the object " + obj.Name + " is not a path. Please select only path and Compounds." return myMachine = None for pathobj in selection: if hasattr(pathobj, "MachineName"): myMachine = pathobj.MachineName if hasattr(pathobj, "MachineUnits"): if pathobj.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" if myMachine is None: print "No machine found in this selection" gcode = "" gcode += HEADER % (FreeCAD.ActiveDocument.FileName) gcode += SAFETYBLOCK gcode += UNITS + "\n" lastcommand = None gcode += COMMENT + selection[0].Description + "\n" gobjects = [] for g in selection[0].Group: gobjects.append(g) for obj in gobjects: for c in obj.Path.Commands: outstring = [] command = c.Name if command[0] == "(": command = PostUtils.fcoms(command, COMMENT) outstring.append(command) if MODAL == True: if command == lastcommand: outstring.pop(0) if c.Parameters >= 1: for param in params: if param in c.Parameters: if param == "F": outstring.append(param + PostUtils.fmt(c.Parameters["F"], FEED_DECIMALS, UNITS)) elif param == "H": outstring.append(param + str(int(c.Parameters["H"]))) elif param == "S": outstring.append( param + PostUtils.fmt(c.Parameters["S"], SPINDLE_DECIMALS, "G21") ) # rpm is unitless-therefore I had to 'fake it out' by using metric units which don't get converted from entered value elif param == "T": outstring.append(param + str(int(c.Parameters["T"]))) else: outstring.append(param + PostUtils.fmt(c.Parameters[param], AXIS_DECIMALS, UNITS)) outstr = str(outstring) outstr = outstr.replace("[", "") outstr = outstr.replace("]", "") outstr = outstr.replace("'", "") outstr = outstr.replace(",", "") gcode += outstr + "\n" lastcommand = c.Name gcode += TOOLRETURN gcode += SAFETYBLOCK gcode += FOOTER if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename, "wb") gfile.write(gcode) gfile.close()
def export(selection,filename): params = ['X','Y','Z','A','B','I','J','F','H','S','T','Q','R','L'] #Using XY plane most of the time so skipping K for obj in selection: if not hasattr(obj,"Path"): print "the object " + obj.Name + " is not a path. Please select only path and Compounds." return myMachine = None for pathobj in selection: if hasattr(pathobj,"Group"): #We have a compound or selection. for p in pathobj.Group: if p.Name == "Machine": myMachine = p if myMachine is None: print "No machine found in this selection" else: if myMachine.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" gcode ='' gcode+= HEADER gcode+= SAFETYBLOCK gcode+= UNITS+'\n' lastcommand = None gcode+= COMMENT+ selection[0].Description +'\n' gobjects = [] for g in selection[0].Group: if g.Name <>'Machine': #filtering out gcode home position from Machine object gobjects.append(g) for obj in gobjects: for c in obj.Path.Commands: outstring = [] command = c.Name if command[0]=='(': command = PostUtils.fcoms(command, COMMENT) outstring.append(command) if MODAL == True: if command == lastcommand: outstring.pop(0) if c.Parameters >= 1: for param in params: if param in c.Parameters: if param == 'F': outstring.append(param + PostUtils.fmt(c.Parameters['F'], FEED_DECIMALS,UNITS)) elif param == 'H': outstring.append(param + str(int(c.Parameters['H']))) elif param == 'S': outstring.append(param + PostUtils.fmt(c.Parameters['S'], SPINDLE_DECIMALS,'G21')) #rpm is unitless-therefore I had to 'fake it out' by using metric units which don't get converted from entered value elif param == 'T': outstring.append(param + str(int(c.Parameters['T']))) else: outstring.append(param + PostUtils.fmt(c.Parameters[param],AXIS_DECIMALS,UNITS)) outstr = str(outstring) outstr =outstr.replace('[','') outstr =outstr.replace(']','') outstr =outstr.replace("'",'') outstr =outstr.replace(",",'') gcode+= outstr + '\n' lastcommand = c.Name gcode+= TOOLRETURN gcode+= SAFETYBLOCK gcode+= FOOTER if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename,"wb") gfile.write(gcode) gfile.close()
def export(selection,filename,argstring): global linenr linenr = STARTLINENR lastX = 0 lastY = 0 lastZ = 0 params = ['X','Y','Z','A','B','I','J','F','H','S','T','Q','R','L'] #Using XY plane most of the time so skipping K modalParamsDict = dict() for mp in MODALPARAMS: modalParamsDict[mp] = None for obj in selection: if not hasattr(obj,"Path"): print "the object " + obj.Name + " is not a path. Please select only path and Compounds." return myMachine = None for pathobj in selection: if hasattr(pathobj,"MachineName"): myMachine = pathobj.MachineName if hasattr(pathobj, "MachineUnits"): if pathobj.MachineUnits == "Metric": UNITS = "G21" else: UNITS = "G20" if myMachine is None: print "No machine found in this selection" gcode ='' gcode+= mkHeader(selection) gcode+= linenumberify(GCODE_HEADER) if UNITS_INCLUDED: gcode += linenumberify(mapGCode(UNITS)) lastcommand = None gobjects = [] for g in selection[0].Group: if g.Name <>'Machine': #filtering out gcode home position from Machine object gobjects.append(g) for obj in gobjects: if hasattr(obj,'Comment'): gcode += linenumberify('(' + obj.Comment + ')') for c in obj.Path.Commands: outstring = [] command = c.Name if (command != UNITS or UNITS_INCLUDED): if command[0]=='(': command = PostUtils.fcoms(command, COMMENT) mappedCommand = mapGCode(command) # the mapping is done for output only! For internal things we still use the old value. if not MODAL or command != lastcommand: outstring.append(mappedCommand) # if MODAL == True: ) # #\better: append iff MODAL == False ) # if command == lastcommand: ) # outstring.pop(0!#\ ) if c.Parameters >= 1: for param in params: if param in c.Parameters: if (param in MODALPARAMS) and (modalParamsDict[str(param)] == c.Parameters[str(param)]): # do nothing or append white space outstring.append(' ') elif param == 'F': outstring.append(param + PostUtils.fmt(c.Parameters['F'], FEED_DECIMALS,UNITS)) elif param == 'H': outstring.append(param + str(int(c.Parameters['H']))) elif param == 'S': outstring.append(param + PostUtils.fmt(c.Parameters['S'], SPINDLE_DECIMALS,'G21')) #rpm is unitless-therefore I had to 'fake it out' by using metric units which don't get converted from entered value elif param == 'T': outstring.append(param + str(int(c.Parameters['T']))) elif param == 'I' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, where relative coordinates have to be changed to absolute i = c.Parameters['I'] # calculate the radius r j = c.Parameters['J'] r = math.sqrt(i**2 + j**2) if USE_RADIUS_IF_POSSIBLE and angleUnder180(command,lastX,lastY,c.Parameters['X'],c.Parameters['Y'],i,j): outstring.append('R' + PostUtils.fmt(r,AXIS_DECIMALS,UNITS)) else: if RADIUS_COMMENT: outstring.append('(R' + PostUtils.fmt(r,AXIS_DECIMALS,UNITS) + ')') if ABSOLUTE_CIRCLE_CENTER: i += lastX outstring.append(param + PostUtils.fmt(i,AXIS_DECIMALS,UNITS)) elif param == 'J' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, where incremental center has to be changed to absolute center i = c.Parameters['I'] j = c.Parameters['J'] if USE_RADIUS_IF_POSSIBLE and angleUnder180(command,lastX,lastY,c.Parameters['X'],c.Parameters['Y'],i,j): # R is handled with the I parameter, here: do nothing at all, keep the structure as with I command pass else: if ABSOLUTE_CIRCLE_CENTER: j += lastY if SWAP_Y_Z: # we have to swap j and k as well outstring.append('K' + PostUtils.fmt(j,AXIS_DECIMALS,UNITS)) else: outstring.append(param + PostUtils.fmt(j,AXIS_DECIMALS,UNITS)) elif param == 'K' and (command == 'G2' or command == 'G3'): # this is the special case for circular paths, where incremental center has to be changed to absolute center outstring.append('(' + param + PostUtils.fmt(c.Parameters[param],AXIS_DECIMALS,UNITS) + ')') z = c.Parameters['Z'] k = c.Parameters['K'] if USE_RADIUS_IF_POSSIBLE and angleUnder180(command,lastX,lastY,c.Parameters['X'],c.Parameters['Y'],i,j): # R is handled with the I parameter, here: do nothing at all, keep the structure as with I command pass else: if ABSOLUTE_CIRCLE_CENTER: k += lastZ if SWAP_Y_Z: # we have to swap j and k as well outstring.append('J' + PostUtils.fmt(j,AXIS_DECIMALS,UNITS)) else: outstring.append(param + PostUtils.fmt(j,AXIS_DECIMALS,UNITS)) elif param == 'Y' and SWAP_Y_Z: outstring.append('Z' + PostUtils.fmt(c.Parameters[param],AXIS_DECIMALS,UNITS)) elif param == 'Z' and SWAP_Y_Z: outstring.append('Y' + PostUtils.fmt(c.Parameters[param],AXIS_DECIMALS,UNITS)) else: outstring.append(param + PostUtils.fmt(c.Parameters[param],AXIS_DECIMALS,UNITS)) if param in MODALPARAMS: modalParamsDict[str(param)] = c.Parameters[param] # save the last X, Y, Z values if 'X' in c.Parameters: lastX = c.Parameters['X'] if 'Y' in c.Parameters: lastY = c.Parameters['Y'] if 'Z' in c.Parameters: lastZ = c.Parameters['Z'] outstr = str(outstring) outstr =outstr.replace(']','') outstr =outstr.replace('[','') outstr =outstr.replace("'",'') outstr =outstr.replace(",",'') if LINENUMBERS: gcode += "N" + str(linenr) + " " linenr += LINENUMBER_INCREMENT gcode+= outstr + '\n' lastcommand = c.Name gcode+= linenumberify(GCODE_FOOTER) if SHOW_EDITOR: PostUtils.editor(gcode) gfile = pythonopen(filename,"wb") gfile.write(gcode) gfile.close()