def parse(pathobj):
    global AXIS_PRECISION
    global FEED_PRECISION
    out = ""
    lastcommand = None
    axis_precision_string = '.' + str(AXIS_PRECISION) +'f'
    feed_precision_string = '.' + str(FEED_PRECISION) +'f'
    # params = ['X','Y','Z','A','B','I','J','K','F','S'] #This list control
    # the order of parameters
    # centroid doesn't want K properties on XY plane  Arcs need work.
    params = ['X', 'Y', 'Z', 'A', 'B', 'I', 'J', 'F', 'S', 'T', 'Q', 'R', 'L', 'H']

    if hasattr(pathobj, "Group"):  # We have a compound or project.
        # if OUTPUT_COMMENTS:
        #     out += linenumber() + "(compound: " + pathobj.Label + ")\n"
        for p in pathobj.Group:
            out += parse(p)
        return out
    else:  # parsing simple path

        # groups might contain non-path things like stock.
        if not hasattr(pathobj, "Path"):
            return out

        # if OUTPUT_COMMENTS:
        #     out += linenumber() + "(" + pathobj.Label + ")\n"

        for c in pathobj.Path.Commands:
            commandlist = [] #list of elements in the command, code and params.
            command = c.Name #command M or G code or comment string

            if command[0]=='(':
                command = PostUtils.fcoms(command, COMMENT)

            commandlist.append(command)
            # if modal: only print the command if it is not the same as the
            # last one
            if MODAL is True:
                if command == lastcommand:
                    commandlist.pop(0)

            # Now add the remaining parameters in order
            for param in params:
                if param in c.Parameters:
                    if param == 'F':
                        if c.Name not in ["G0", "G00"]: #centroid doesn't use rapid speeds
                            speed = Units.Quantity(c.Parameters['F'], FreeCAD.Units.Velocity)
                            commandlist.append(
                                param + format(float(speed.getValueAs(UNIT_FORMAT)), feed_precision_string) )
                    elif param == 'H':
                        commandlist.append(param + str(int(c.Parameters['H'])))
                    elif param == 'S':
                        commandlist.append(param + PostUtils.fmt(c.Parameters['S'], SPINDLE_DECIMALS, "G21"))
                    elif param == 'T':
                        commandlist.append(param + str(int(c.Parameters['T'])))
                    else:
                        commandlist.append(
                            param + format(c.Parameters[param], axis_precision_string))
            outstr = str(commandlist)
            outstr =outstr.replace('[','')
            outstr =outstr.replace(']','')
            outstr =outstr.replace("'",'')
            outstr =outstr.replace(",",'')
            #out += outstr + '\n'

            # store the latest command
            lastcommand = command

            # Check for Tool Change:
            if command == 'M6':
                # if OUTPUT_COMMENTS:
                #     out += linenumber() + "(begin toolchange)\n"
                for line in TOOL_CHANGE.splitlines(True):
                    out += linenumber() + line

            # if command == "message":
            #     if OUTPUT_COMMENTS is False:
            #         out = []
            #     else:
            #         commandlist.pop(0)  # remove the command

            # prepend a line number and append a newline
            if len(commandlist) >= 1:
                if OUTPUT_LINE_NUMBERS:
                    commandlist.insert(0, (linenumber()))

                # append the line to the final output
                for w in commandlist:
                    out += w + COMMAND_SPACE
                out = out.strip() + "\n"

        return out
Example #2
0
def parse(pathobj):
    out = ""
    lastcommand = None
    axis_precision_string = '.' + str(AXIS_PRECISION) + 'f'
    feed_precision_string = '.' + str(FEED_PRECISION) + 'f'
    # params = ['X','Y','Z','A','B','I','J','K','F','S'] #This list control
    # the order of parameters
    # centroid doesn't want K properties on XY plane  Arcs need work.
    params = [
        'X', 'Y', 'Z', 'A', 'B', 'I', 'J', 'F', 'S', 'T', 'Q', 'R', 'L', 'H'
    ]

    if hasattr(pathobj, "Group"):  # We have a compound or project.
        # if OUTPUT_COMMENTS:
        #     out += linenumber() + "(compound: " + pathobj.Label + ")\n"
        for p in pathobj.Group:
            out += parse(p)
        return out
    else:  # parsing simple path

        # groups might contain non-path things like stock.
        if not hasattr(pathobj, "Path"):
            return out

        # if OUTPUT_COMMENTS:
        #     out += linenumber() + "(" + pathobj.Label + ")\n"

        for c in pathobj.Path.Commands:
            commandlist = [
            ]  # list of elements in the command, code and params.
            command = c.Name  # command M or G code or comment string

            if command[0] == '(':
                command = PostUtils.fcoms(command, COMMENT)

            commandlist.append(command)
            # if modal: only print the command if it is not the same as the
            # last one
            if MODAL is True:
                if command == lastcommand:
                    commandlist.pop(0)

            # Now add the remaining parameters in order
            for param in params:
                if param in c.Parameters:
                    if param == 'F':
                        if c.Name not in [
                                "G0", "G00"
                        ]:  # centroid doesn't use rapid speeds
                            speed = Units.Quantity(c.Parameters['F'],
                                                   FreeCAD.Units.Velocity)
                            commandlist.append(
                                param +
                                format(float(speed.getValueAs(UNIT_FORMAT)),
                                       feed_precision_string))
                    elif param == 'H':
                        commandlist.append(param + str(int(c.Parameters['H'])))
                    elif param == 'S':
                        commandlist.append(param + PostUtils.fmt(
                            c.Parameters['S'], SPINDLE_DECIMALS, "G21"))
                    elif param == 'T':
                        commandlist.append(param + str(int(c.Parameters['T'])))
                    else:
                        commandlist.append(
                            param +
                            format(c.Parameters[param], axis_precision_string))
            outstr = str(commandlist)
            outstr = outstr.replace('[', '')
            outstr = outstr.replace(']', '')
            outstr = outstr.replace("'", '')
            outstr = outstr.replace(",", '')

            # store the latest command
            lastcommand = command

            # Check for Tool Change:
            if command == 'M6':
                # if OUTPUT_COMMENTS:
                #     out += linenumber() + "(begin toolchange)\n"
                for line in TOOL_CHANGE.splitlines(True):
                    out += linenumber() + line

            # if command == "message":
            #     if OUTPUT_COMMENTS is False:
            #         out = []
            #     else:
            #         commandlist.pop(0)  # remove the command

            # prepend a line number and append a newline
            if len(commandlist) >= 1:
                if OUTPUT_LINE_NUMBERS:
                    commandlist.insert(0, (linenumber()))

                # append the line to the final output
                for w in commandlist:
                    out += w + COMMAND_SPACE
                out = out.strip() + "\n"

        return out
Example #3
0
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()
Example #4
0
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()
Example #5
0
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()
Example #6
0
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()
Example #7
0
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()
Example #8
0
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()
Example #9
0
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()
Example #10
0
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()
Example #12
0
def parse(values, pathobj):
    """Parse a Path."""
    out = ""
    lastcommand = None
    axis_precision_string = "." + str(values["AXIS_PRECISION"]) + "f"
    feed_precision_string = "." + str(values["FEED_PRECISION"]) + "f"

    currLocation = {}  # keep track for no doubles
    firstmove = Path.Command("G0", {"X": -1, "Y": -1, "Z": -1, "F": 0.0})
    currLocation.update(firstmove.Parameters)  # set First location Parameters

    if hasattr(pathobj, "Group"):  # We have a compound or project.
        if values["OUTPUT_COMMENTS"]:
            comment = create_comment("Compound: " + pathobj.Label,
                                     values["COMMENT_SYMBOL"])
            out += linenumber(values) + comment + "\n"
        for p in pathobj.Group:
            out += parse(values, p)
        return out
    else:  # parsing simple path

        # groups might contain non-path things like stock.
        if not hasattr(pathobj, "Path"):
            return out

        if values["OUTPUT_PATH_LABELS"] and values["OUTPUT_COMMENTS"]:
            comment = create_comment("Path: " + pathobj.Label,
                                     values["COMMENT_SYMBOL"])
            out += linenumber(values) + comment + "\n"

        if values["OUTPUT_ADAPTIVE"]:
            adaptiveOp = False
            opHorizRapid = 0
            opVertRapid = 0
            if "Adaptive" in pathobj.Name:
                adaptiveOp = True
                if hasattr(pathobj, "ToolController"):
                    if (hasattr(pathobj.ToolController, "HorizRapid")
                            and pathobj.ToolController.HorizRapid > 0):
                        opHorizRapid = Units.Quantity(
                            pathobj.ToolController.HorizRapid,
                            FreeCAD.Units.Velocity)
                    else:
                        FreeCAD.Console.PrintWarning(
                            "Tool Controller Horizontal Rapid Values are unset"
                            + "\n")
                    if (hasattr(pathobj.ToolController, "VertRapid")
                            and pathobj.ToolController.VertRapid > 0):
                        opVertRapid = Units.Quantity(
                            pathobj.ToolController.VertRapid,
                            FreeCAD.Units.Velocity)
                    else:
                        FreeCAD.Console.PrintWarning(
                            "Tool Controller Vertical Rapid Values are unset" +
                            "\n")

        for c in pathobj.Path.Commands:

            # List of elements in the command, code, and params.
            outstring = []
            # command M or G code or comment string
            command = c.Name
            if command[0] == "(":
                if values["OUTPUT_COMMENTS"]:
                    if values["COMMENT_SYMBOL"] != "(":
                        command = PostUtils.fcoms(command,
                                                  values["COMMENT_SYMBOL"])
                else:
                    continue
            if values["OUTPUT_ADAPTIVE"]:
                if adaptiveOp and command in values["RAPID_MOVES"]:
                    if opHorizRapid and opVertRapid:
                        command = "G1"
                    else:
                        outstring.append(
                            "(Tool Controller Rapid Values are unset)" + "\n")

            outstring.append(command)

            # if modal: suppress the command if it is the same as the last one
            if values["MODAL"]:
                if command == lastcommand:
                    outstring.pop(0)

            # Now add the remaining parameters in order
            for param in values["PARAMETER_ORDER"]:
                if param in c.Parameters:
                    if param == "F" and (
                            currLocation[param] != c.Parameters[param]
                            or values["OUTPUT_DOUBLES"]):
                        # centroid and linuxcnc don't use rapid speeds
                        if command not in values["RAPID_MOVES"]:
                            speed = Units.Quantity(c.Parameters["F"],
                                                   FreeCAD.Units.Velocity)
                            if speed.getValueAs(
                                    values["UNIT_SPEED_FORMAT"]) > 0.0:
                                outstring.append(param + format(
                                    float(
                                        speed.getValueAs(
                                            values["UNIT_SPEED_FORMAT"])),
                                    feed_precision_string,
                                ))
                        else:
                            continue
                    elif param in ["H", "L", "T"]:
                        outstring.append(param + str(int(c.Parameters[param])))
                    elif param == "D":
                        if command in ["G41", "G42"]:
                            outstring.append(param +
                                             str(int(c.Parameters[param])))
                        elif command in ["G96", "G97"]:
                            outstring.append(param + PostUtils.fmt(
                                c.Parameters[param],
                                values["SPINDLE_DECIMALS"],
                                "G21",
                            ))
                        else:  # anything else that is supported (G41.1?, G42.1?)
                            outstring.append(param +
                                             str(float(c.Parameters[param])))
                    elif param == "P":
                        if command in [
                                "G2", "G02", "G3", "G03", "G5.2", "G5.3", "G10"
                        ]:
                            outstring.append(param +
                                             str(int(c.Parameters[param])))
                        elif command in [
                                "G4",
                                "G04",
                                "G64",
                                "G76",
                                "G82",
                                "G86",
                                "G89",
                        ]:
                            outstring.append(param +
                                             str(float(c.Parameters[param])))
                        elif command in ["G5", "G05"]:
                            pos = Units.Quantity(c.Parameters[param],
                                                 FreeCAD.Units.Length)
                            outstring.append(param + format(
                                float(pos.getValueAs(values["UNIT_FORMAT"])),
                                axis_precision_string,
                            ))
                        else:  # anything else that is supported
                            outstring.append(param + str(c.Parameters[param]))
                    elif param == "S":
                        outstring.append(
                            param +
                            PostUtils.fmt(c.Parameters[param],
                                          values["SPINDLE_DECIMALS"], "G21"))
                    else:
                        if ((not values["OUTPUT_DOUBLES"])
                                and (param in currLocation) and
                            (currLocation[param] == c.Parameters[param])):
                            continue
                        else:
                            pos = Units.Quantity(c.Parameters[param],
                                                 FreeCAD.Units.Length)
                            outstring.append(param + format(
                                float(pos.getValueAs(values["UNIT_FORMAT"])),
                                axis_precision_string,
                            ))

            if values["OUTPUT_ADAPTIVE"]:
                if adaptiveOp and command in values["RAPID_MOVES"]:
                    if opHorizRapid and opVertRapid:
                        if "Z" not in c.Parameters:
                            outstring.append("F" + format(
                                float(
                                    opHorizRapid.getValueAs(
                                        values["UNIT_SPEED_FORMAT"])),
                                axis_precision_string,
                            ))
                        else:
                            outstring.append("F" + format(
                                float(
                                    opVertRapid.getValueAs(
                                        values["UNIT_SPEED_FORMAT"])),
                                axis_precision_string,
                            ))

            # store the latest command
            lastcommand = command

            currLocation.update(c.Parameters)
            # Memorizes the current position for calculating the related movements
            # and the withdrawal plan
            if command in values["MOTION_COMMANDS"]:
                if "X" in c.Parameters:
                    values["CURRENT_X"] = Units.Quantity(
                        c.Parameters["X"], FreeCAD.Units.Length)
                if "Y" in c.Parameters:
                    values["CURRENT_Y"] = Units.Quantity(
                        c.Parameters["Y"], FreeCAD.Units.Length)
                if "Z" in c.Parameters:
                    values["CURRENT_Z"] = Units.Quantity(
                        c.Parameters["Z"], FreeCAD.Units.Length)

            if command in ("G98", "G99"):
                values["DRILL_RETRACT_MODE"] = command

            if command in ("G90", "G91"):
                values["MOTION_MODE"] = command

            if values["TRANSLATE_DRILL_CYCLES"]:
                if command in values["DRILL_CYCLES_TO_TRANSLATE"]:
                    out += drill_translate(values, outstring, command,
                                           c.Parameters)
                    # Erase the line we just translated
                    outstring = []

            if values["SPINDLE_WAIT"] > 0:
                if command in ("M3", "M03", "M4", "M04"):
                    out += (linenumber(values) +
                            format_outstring(values, outstring) + "\n")
                    out += (linenumber(values) + format_outstring(
                        values, ["G4", "P%s" % values["SPINDLE_WAIT"]]) + "\n")
                    outstring = []

            # Check for Tool Change:
            if command in ("M6", "M06"):
                if values["OUTPUT_COMMENTS"]:
                    comment = create_comment("Begin toolchange",
                                             values["COMMENT_SYMBOL"])
                    out += linenumber(values) + comment + "\n"
                if values["OUTPUT_TOOL_CHANGE"]:
                    if values["STOP_SPINDLE_FOR_TOOL_CHANGE"]:
                        # stop the spindle
                        out += linenumber(values) + "M5\n"
                    for line in values["TOOL_CHANGE"].splitlines(False):
                        out += linenumber(values) + line + "\n"
                else:
                    if values["OUTPUT_COMMENTS"]:
                        # convert the tool change to a comment
                        comment = create_comment(
                            values["COMMAND_SPACE"] +
                            format_outstring(values, outstring) +
                            values["COMMAND_SPACE"],
                            values["COMMENT_SYMBOL"],
                        )
                        out += linenumber(values) + comment + "\n"
                        outstring = []

            if command == "message" and values["REMOVE_MESSAGES"]:
                if values["OUTPUT_COMMENTS"] is False:
                    out = []
                else:
                    outstring.pop(0)  # remove the command

            if command in values["SUPPRESS_COMMANDS"]:
                if values["OUTPUT_COMMENTS"]:
                    # convert the command to a comment
                    comment = create_comment(
                        values["COMMAND_SPACE"] +
                        format_outstring(values, outstring) +
                        values["COMMAND_SPACE"],
                        values["COMMENT_SYMBOL"],
                    )
                    out += linenumber(values) + comment + "\n"
                # remove the command
                outstring = []

            # prepend a line number and append a newline
            if len(outstring) >= 1:
                if values["OUTPUT_LINE_NUMBERS"]:
                    # In this case we don't want a space after the line number
                    # because the space is added in the join just below.
                    outstring.insert(0, (linenumber(values, "")))

                # append the line to the final output
                out += values["COMMAND_SPACE"].join(outstring)
                # Note: Do *not* strip `out`, since that forces the allocation
                # of a contiguous string & thus quadratic complexity.
                out += "\n"

            # add height offset
            if command in ("M6", "M06") and values["USE_TLO"]:
                out += linenumber(values) + "G43 H" + str(
                    int(c.Parameters["T"])) + "\n"

            # Check for comments containing machine-specific commands
            # to pass literally to the controller
            if values["ENABLE_MACHINE_SPECIFIC_COMMANDS"]:
                m = re.match(r"^\(MC_RUN_COMMAND: ([^)]+)\)$", command)
                if m:
                    raw_command = m.group(1)
                    out += linenumber(values) + raw_command + "\n"

        return out