Example #1
0
def parse(inputstring):
    "parse(inputstring): returns a parsed output string"
    print "postprocessing..."

    output = ""
    params = ['X', 'Y', 'Z', 'A', 'B', 'I', 'J', 'K', 'F', 'S',
              'T']  #This list control the order of parameters

    # write some stuff first
    if OUTPUT_HEADER:
        print "outputting header"
        output += "'Exported by FreeCAD\n"
        output += "'Post Processor: " + __name__ + "\n"
        output += "'Output Time:" + str(now) + "\n"

    #Write the preamble
    if OUTPUT_COMMENTS: output += "'begin preamble\n"
    for line in PREAMBLE.splitlines(True):
        output += line

    # treat the input line by line
    lines = inputstring.splitlines(True)

    for line in lines:
        commandline = PostUtils.stringsplit(line)
        command = commandline['command']
        try:
            print commandline
            print "command: " + command
            print command in scommands
            output += scommands[command](commandline)
        except:
            print "I don't know what the hell the command:  " + command + " means.  Maybe I should support it."

    print "finished"
    # write some more stuff at the end
    if OUTPUT_COMMENTS: output += "'begin postamble\n"
    for line in POSTAMBLE.splitlines(True):
        output += line

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(output)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = output
    else:
        final = output

    print "done postprocessing."
    return final
Example #2
0
def export(obj, filename, argstring):
    modal = True
    gcode = ""
    safetyblock1 = "G90G40G49\n"
    gcode += safetyblock1

    units = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units")
    if units.GetInt("UserSchema") == 0:
        firstcommand = Path.Command("G21")  # metric mode
    else:
        firstcommand = Path.Command("G20")  # inch mode
    oldvals = saveVals(firstcommand)  # save first command for modal use
    fp = obj[0]
    gcode += firstcommand.Name

    if hasattr(fp, "Path"):
        for c in fp.Path.Commands:
            gcode += lineout(c, oldvals, modal) + "\n"
            oldvals = saveVals(c)
        gcode += "M2\n"
        gfile = open(filename, "w")
        gfile.write(gcode)
        gfile.close()
    else:
        FreeCAD.Console.PrintError("Select a path object and try again\n")

    if SHOW_EDITOR:
        FreeCAD.Console.PrintMessage("Editor Activated\n")
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        dia.exec_()
Example #3
0
def export(obj, filename):
    modal = True
    commands = obj[0]
    gcode = ''
    safetyblock1 = 'G90G40G49\n'
    gcode += safetyblock1

    units = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units")
    if units.GetInt('UserSchema') == 0:
        firstcommand = Path.Command('G21')  #metric mode
    else:
        firstcommand = Path.Command('G20')  #inch mode
    oldvals = saveVals(firstcommand)  #save first command for modal use
    fp = obj[0]
    gcode += firstcommand.Name

    if hasattr(fp, "Path"):
        for c in fp.Path.Commands:
            gcode += lineout(c, oldvals, modal) + '\n'
            oldvals = saveVals(c)
        gcode += 'M2\n'
        gfile = open(filename, "wb")
        gfile.write(gcode)
        gfile.close()
    else:
        FreeCAD.Console.PrintError('Select a path object and try again\n')
    if obj[0].Editor:
        FreeCAD.Console.PrintMessage('Editor Activated\n')
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        dia.exec_()
Example #4
0
def export(objectslist, filename, argstring):
    "called when freecad exports a list of objects"
    # pylint: disable=unused-argument

    output = '''(This output produced with the dump post processor)
(Dump is useful for inspecting the raw commands in your paths)
(but is not useful for driving machines.)
(Consider setting a default postprocessor in your project or )
(exporting your paths using a specific post that matches your machine)

'''

    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
        print("postprocessing...")
        output += parse(obj)

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(output)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = output
    else:
        final = output

    print("done postprocessing.")
    return final
Example #5
0
    def test010(self):
        """Test the utility functions in the PostUtils.py file."""
        commands = [
            Path.Command("G1 X-7.5 Y5.0 Z0.0"),
            Path.Command("G2 I2.5 J0.0 K0.0 X-5.0 Y7.5 Z0.0"),
            Path.Command("G1 X5.0 Y7.5 Z0.0"),
            Path.Command("G2 I0.0 J-2.5 K0.0 X7.5 Y5.0 Z0.0"),
            Path.Command("G1 X7.5 Y-5.0 Z0.0"),
            Path.Command("G2 I-2.5 J0.0 K0.0 X5.0 Y-7.5 Z0.0"),
            Path.Command("G1 X-5.0 Y-7.5 Z0.0"),
            Path.Command("G2 I0.0 J2.5 K0.0 X-7.5 Y-5.0 Z0.0"),
            Path.Command("G1 X-7.5 Y0.0 Z0.0"),
        ]

        testpath = Path.Path(commands)
        self.assertTrue(len(testpath.Commands) == 9)
        self.assertTrue(
            len([c for c in testpath.Commands if c.Name in ["G2", "G3"]]) == 4
        )

        results = PostUtils.splitArcs(testpath)
        # self.assertTrue(len(results.Commands) == 117)
        self.assertTrue(
            len([c for c in results.Commands if c.Name in ["G2", "G3"]]) == 0
        )
Example #6
0
def export(objectslist, filename, argstring):
    """Export the list of objects into a filename.

    Parameters
    ----------
    objectslists: list
        List of objects.

    filename: str
        Name of the output file ending in `'.knc'`.
    """
    gcode = HEADER

    for obj in objectslist:
        for command in obj.Path.Commands:
            # Manipulate tool change commands
            if "M6" == command.Name:
                gcode += TOOL_CHANGE.replace("TOOL",
                                             str(int(command.Parameters["T"])))
            elif "M3" == command.Name:
                # Convert spindle speed (rpm) command to comment
                gcode += ("M01 Set spindle speed to " +
                          str(int(command.Parameters["S"])) +
                          " rounds per minute")
            else:
                # Add other commands
                gcode += command.Name

                # Loop through command parameters
                for parameter, value in command.Parameters.items():
                    # Multiply F parameter value by 10,
                    # FreeCAD = mm/s, nccad = 1/10 mm/s
                    if "F" == parameter:
                        value *= 10
                    # Add command parameters and values and round float
                    # as nccad9 does not support exponents
                    gcode += " " + parameter + str(round(value, 5))

            gcode += "\n"

    gcode += POSTAMBLE + "\n"

    # Open editor window
    if FreeCAD.GuiUp:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            gcode = dia.editor.toPlainText()

    # Save to file
    if filename != "-":
        gfile = open(filename, "w")
        gfile.write(gcode)
        gfile.close()

    return filename
Example #7
0
def parse(inputstring):
    "parse(inputstring): returns a parsed output string"
    print "postprocessing..."
    
    output = ""
    params = ['X','Y','Z','A','B','I','J','K','F','S','T'] #This list control the order of parameters
 
    # write some stuff first
    if OUTPUT_HEADER:
        print "outputting header"
        output += "'Exported by FreeCAD\n"
        output += "'Post Processor: " + __name__ +"\n"
        output += "'Output Time:"+str(now)+"\n"

    #Write the preamble 
    if OUTPUT_COMMENTS: output += "'begin preamble\n"
    for line in PREAMBLE.splitlines(True):
        output += line

    # treat the input line by line
    lines = inputstring.splitlines(True)

    for line in lines:
        commandline = PostUtils.stringsplit(line)
        command = commandline['command']        
        try:
            print commandline
            print "command: " + command
            print command in scommands
            output += scommands[command](commandline)
        except:
            print "I don't know what the hell the command:  " + command + " means.  Maybe I should support it."

    print "finished"    
    # write some more stuff at the end
    if OUTPUT_COMMENTS: output += "'begin postamble\n" 
    for line in POSTAMBLE.splitlines(True):
        output += line

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(output)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = output
    else:
        final = output

    print "done postprocessing."
    return final
Example #8
0
def export(objectslist, filename, argstring):

    gcode = HEADER

    for obj in objectslist:

        for command in obj.Path.Commands:

            # Manipulate tool change commands
            if 'M6' == command.Name:
                gcode += TOOL_CHANGE.replace('TOOL',
                                             str(int(command.Parameters['T'])))

            # Convert spindle speed (rpm) command to comment
            elif 'M3' == command.Name:
                gcode += 'M01 Set spindle speed to ' + str(
                    int(command.Parameters['S'])) + ' rounds per minute'

            # Add other commands
            else:
                gcode += command.Name

                # Loop through command parameters
                for parameter, value in command.Parameters.items():

                    # Multiply F parameter value by 10 (FreeCAD = mm/s, nccad = 1/10 mm/s)
                    if 'F' == parameter:
                        value *= 10

                    # Add command parameters and values and round float as nccad9 does not support exponents
                    gcode += ' ' + parameter + str(round(value, 5))

            gcode += '\n'

    gcode += POSTAMBLE + '\n'

    # Open editor window
    if FreeCAD.GuiUp:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            gcode = dia.editor.toPlainText()

    # Save to file
    if filename != '-':
        gfile = open(filename, "w")
        gfile.write(gcode)
        gfile.close()

    return filename
Example #9
0
def parse(inputstring):
    "parse(inputstring): returns a parsed output string"

    state = {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'XYspeed': -1.0, 'Zspeed': -1.0}
    output = []

    # header
    output += addheader()
    output += motoron()

    output += speed(2.0, 1.0, state)  # defaults

    # TODO: respect clearance height

    # treat the input line by line
    lines = inputstring.split("\n")
    for line in lines:
        if not line:
            continue
        parsed = PostUtils.stringsplit(line)
        command = parsed['command']
        print('cmd', line)
        try:
            if command:
                code = convertgcode(command, parsed, state)
                if not isinstance(code, list):
                    code = [code]
                if len(code) and code[0]:
                    output += code
        except NotImplementedError as e:
            print(e)

    # footer
    output += motoroff()
    output += home()
    output += addfooter()

    return '\n'.join(output)
Example #10
0
def parse(inputstring):
    "parse(inputstring): returns a parsed output string"

    state = { 'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'XYspeed': -1.0, 'Zspeed': -1.0 }
    output = []

    # header
    output += addheader()
    output += motoron()

    output += speed(2.0, 1.0, state) # defaults

    # TODO: respect clearance height

    # treat the input line by line
    lines = inputstring.split("\n")
    for line in lines:
        if not line:
            continue
        parsed = PostUtils.stringsplit(line)
        command = parsed['command']
        print('cmd', line)
        try:
            if command:
                code = convertgcode(command, parsed, state)
                if not isinstance(code, list):
                    code = [ code ]
                if len(code) and code[0]:
                    output += code
        except NotImplementedError as e:
            print(e)

    # footer
    output += motoroff()
    output += home()
    output += addfooter()

    return '\n'.join(output)
Example #11
0
    def testSplitArcs(self):

        commands = [
            Path.Command("G1 X-7.5 Y5.0 Z0.0"),
            Path.Command("G2 I2.5 J0.0 K0.0 X-5.0 Y7.5 Z0.0"),
            Path.Command("G1 X5.0 Y7.5 Z0.0"),
            Path.Command("G2 I0.0 J-2.5 K0.0 X7.5 Y5.0 Z0.0"),
            Path.Command("G1 X7.5 Y-5.0 Z0.0"),
            Path.Command("G2 I-2.5 J0.0 K0.0 X5.0 Y-7.5 Z0.0"),
            Path.Command("G1 X-5.0 Y-7.5 Z0.0"),
            Path.Command("G2 I0.0 J2.5 K0.0 X-7.5 Y-5.0 Z0.0"),
            Path.Command("G1 X-7.5 Y0.0 Z0.0"),
        ]

        testpath = Path.Path(commands)
        self.assertTrue(len(testpath.Commands) == 9)
        self.assertTrue(
            len([c for c in testpath.Commands if c.Name in ['G2', 'G3']]) == 4)

        results = PostUtils.splitArcs(testpath)
        # self.assertTrue(len(results.Commands) == 117)
        self.assertTrue(
            len([c for c in results.Commands if c.Name in ['G2', 'G3']]) == 0)
Example #12
0
def export(objectslist, filename, argstring):
    # pylint: disable=global-statement
    if not processArguments(argstring):
        return None
    global UNITS
    global UNIT_FORMAT
    global UNIT_SPEED_FORMAT

    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 None

    print("postprocessing...")
    gcode = ""

    # write header
    if OUTPUT_HEADER:
        gcode += linenumber() + "(Exported by FreeCAD)\n"
        gcode += linenumber() + "(Post Processor: " + __name__ + ")\n"
        gcode += linenumber() + "(Output Time:" + str(now) + ")\n"

    # Write the preamble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(begin preamble)\n"
    for line in PREAMBLE.splitlines(False):
        gcode += linenumber() + line + "\n"
    gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:

        # Skip inactive operations
        if hasattr(obj, 'Active'): 
            if not obj.Active:
                continue
        if hasattr(obj, 'Base') and hasattr(obj.Base, 'Active'):
            if not obj.Base.Active:
                continue

        # fetch machine details
        job = PathUtils.findParentJob(obj)

        myMachine = 'not set'

        if hasattr(job, "MachineName"):
            myMachine = job.MachineName

        if hasattr(job, "MachineUnits"):
            if job.MachineUnits == "Metric":
                UNITS = "G21"
                UNIT_FORMAT = 'mm'
                UNIT_SPEED_FORMAT = 'mm/min'
            else:
                UNITS = "G20"
                UNIT_FORMAT = 'in'
                UNIT_SPEED_FORMAT = 'in/min'

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(begin operation: %s)\n" % obj.Label
            gcode += linenumber() + "(machine: %s, %s)\n" % (myMachine, UNIT_SPEED_FORMAT)
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        # get coolant mode
        coolantMode = 'None'
        if hasattr(obj, "CoolantMode") or hasattr(obj, 'Base') and  hasattr(obj.Base, "CoolantMode"):
            if hasattr(obj, "CoolantMode"):
                coolantMode = obj.CoolantMode
            else:
                coolantMode = obj.Base.CoolantMode

        # turn coolant on if required
        if OUTPUT_COMMENTS:
            if not coolantMode == 'None':
                gcode += linenumber() + '(Coolant On:' + coolantMode + ')\n'
        if coolantMode == 'Flood':
            gcode  += linenumber() + 'M8' + '\n'
        if coolantMode == 'Mist':
            gcode += linenumber() + 'M7' + '\n'

        # process the operation gcode
        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(finish operation: %s)\n" % obj.Label
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

        # turn coolant off if required
        if not coolantMode == 'None':
            if OUTPUT_COMMENTS:
                gcode += linenumber() + '(Coolant Off:' + coolantMode + ')\n'    
            gcode  += linenumber() +'M9' + '\n'

    # do the post_amble
    if OUTPUT_COMMENTS:
        gcode += "(begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    if FreeCAD.GuiUp and SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    if not filename == '-':
        gfile = pythonopen(filename, "w")
        gfile.write(final)
        gfile.close()

    return final
Example #13
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 #14
0
def export(objectslist, filename, argstring):

    if not processArguments(argstring):
        print("export: process arguments failed, '{}'".format(argstring))
        return None

    global warnings_count
    global problems_count

    warnings_count = 0
    problems_count = 0

    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 None

    print("export: postprocessing...")
    gcode = append0("%" + PROG_NAME + "\n")
    if not argstring:
        gcode += append("(" + __name__ + " with default settings)\n")
    else:
        gcode += append("({} {})\n".format(__name__, argstring))

    # write header
    if OUTPUT_HEADER:
        for line in HEADER.format(
                GCODE_PROCESSOR,
                __name__,
                VERSION,
                FreeCAD.ActiveDocument.FileName,
                str(now),
        ).splitlines(False):
            if line:
                gcode += append(line + "\n")

    # Write the preamble
    # G20/G21 not supported by UC-CNC, *always* report the configured units.
    gcode += append("(Units: '" + UNIT_FORMAT + "' and '" + UNIT_SPEED_FORMAT +
                    "')\n")
    if UNIT_DEFAULT_CHANGED:
        gcode += append(
            "(WARNING: Units default changed, check your UC-CNC profile)\n")
        warnings_count += 1

    if OUTPUT_COMMENTS:
        gcode += append("(preamble: begin)\n")
        # for obj in objectslist:
        #    if isinstance(obj.Proxy, PathScripts.PathToolController.ToolController):
        #        gcode += append("(T{}={})\n".format(obj.ToolNumber, item.Name))
        # error: global name 'PathScripts' is not defined
    for line in PREAMBLE.splitlines(False):
        gcode += append(line + "\n")
    if OUTPUT_COMMENTS:
        gcode += append("(preamble: done)\n")

    # write the code body
    for obj in objectslist:

        # pre_op
        if OUTPUT_COMMENTS:
            gcode += append("(operation initialise: %s)\n" % obj.Label)
        for line in PRE_OPERATION.splitlines(True):
            gcode += append(line)

        # turn coolant on if required
        if hasattr(obj, "CoolantMode"):
            coolantMode = obj.CoolantMode
            if coolantMode == "Mist":
                if OUTPUT_COMMENTS:
                    gcode += append("M7 (coolant: mist on)\n")
                else:
                    gcode += append("M7\n")
            if coolantMode == "Flood":
                if OUTPUT_COMMENTS:
                    gcode += append("M8 (coolant: flood on)\n")
                else:
                    gcode += append("M8\n")

        # process the operation gcode
        if OUTPUT_COMMENTS:
            gcode += append("(operation start: %s)\n" % obj.Label)
        gcode += parse(obj)
        if OUTPUT_COMMENTS:
            gcode += append("(operation done: %s)\n" % obj.Label)

        # post_op
        for line in POST_OPERATION.splitlines(True):
            gcode += append(line)

        # turn coolant off if required
        if hasattr(obj, "CoolantMode"):
            coolantMode = obj.CoolantMode
            if not coolantMode == "None":
                if OUTPUT_COMMENTS:
                    gcode += append("M9 (coolant: off)\n")
                else:
                    gcode += append("M9\n")
        if OUTPUT_COMMENTS:
            gcode += append("(operation finalised: %s)\n" % obj.Label)

    # do the post_amble
    if OUTPUT_COMMENTS:
        gcode += append("(postamble: begin)\n")
    for line in POSTAMBLE.splitlines(True):
        gcode += append(line)
    if OUTPUT_COMMENTS:
        gcode += append("(postamble: done)\n")

    # Show the results
    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    if (0 < problems_count) or (0 < warnings_count):
        print(
            "export: postprocessing: done, warnings: {}, problems: {}, see GCode for details."
            .format(warnings_count, problems_count))
    else:
        print("export: postprocessing: done (none of the problems detected).")

    if not filename == "-":
        print("export: writing to '{}'".format(filename))
        gfile = pythonopen(filename, "w")
        gfile.write(final)
        gfile.close()

    return final
Example #15
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 #16
0
def export(objectslist, filename, argstring):
    processArguments(argstring)
    for i in objectslist:
        print(i.Name)
    global UNITS
    global UNIT_FORMAT

    # ISJOB = (len(objectslist) == 1) and isinstance(objectslist[0].Proxy, PathScripts.PathJob.ObjectJob)
    # print("isjob: {} {}".format(ISJOB, len(objectslist)))

    # if len(objectslist) > 1:
    #     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

    print("postprocessing...")
    gcode = ""

    # write header
    if OUTPUT_HEADER:
        gcode += HEADER

    gcode += SAFETYBLOCK

    # Write the preamble
    if OUTPUT_COMMENTS:
        for item in objectslist:
            if isinstance(item.Proxy,
                          PathScripts.PathToolController.ToolController):
                gcode += ";T{}={}\n".format(item.ToolNumber, item.Name)
        gcode += linenumber() + ";begin preamble\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line

    gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:
        #skip postprocessing tools
        # if isinstance (obj.Proxy, PathScripts.PathToolController.ToolController):
        #     continue

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + ";begin operation\n"
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + ";end operation: %s\n" % obj.Label
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble

    if OUTPUT_COMMENTS:
        gcode += ";begin postamble\n"
    for line in TOOLRETURN.splitlines(True):
        gcode += linenumber() + line
    for line in SAFETYBLOCK.splitlines(True):
        gcode += linenumber() + line
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    if not filename == '-':
        gfile = pythonopen(filename, "wb")
        gfile.write(final)
        gfile.close()

    return final
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 #18
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 #19
0
def export(objectslist, filename, argstring):
    if not processArguments(argstring):
        return None

    global UNITS
    global UNIT_FORMAT
    global UNIT_FEED_FORMAT
    global MOTION_MODE
    global SUPPRESS_COMMANDS

    print('Post Processor: ' + __name__ + ' postprocessing...')
    gcode = ''

    # Write header:
    if OUTPUT_HEADER:
        gcode += linenumber() + '(Exported by FreeCAD)\n'
        gcode += linenumber() + '(Post Processor: ' + __name__
        gcode += '.py, version: ' + Revised + ')\n'
        gcode += linenumber() + '(Output Time:' + str(datetime.now()) + ')\n'

    # Suppress drill-cycle commands:
    if TRANSLATE_DRILL_CYCLES:
        SUPPRESS_COMMANDS += ['G80', 'G98', 'G99']

    # Write the preamble:
    if OUTPUT_COMMENTS:
        gcode += linenumber() + '(Begin preamble)\n'
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line

    # Write these settings AFTER the preamble,
    # to prevent the preamble from changing these:
    if OUTPUT_COMMENTS:
        gcode += linenumber() + '(Default Configuration)\n'
    gcode += linenumber() + MOTION_MODE + '\n'
    gcode += linenumber() + UNITS + '\n'
    gcode += linenumber() + WORK_PLANE + '\n'

    for obj in objectslist:
        # Debug...
        # print('\n' + '*'*70 + '\n')
        # dump(obj)
        # print('\n' + '*'*70 + '\n')
        if not hasattr(obj, 'Path'):
            print('The object ' + obj.Name +
                  ' is not a path. Please select only path and Compounds.')
            return

        # Skip inactive operations:
        if PathUtil.opProperty(obj, 'Active') is False:
            continue

        # Do the pre_op:
        if OUTPUT_BCNC:
            gcode += linenumber() + '(Block-name: ' + obj.Label + ')\n'
            gcode += linenumber() + '(Block-expand: 0)\n'
            gcode += linenumber() + '(Block-enable: 1)\n'
        if OUTPUT_COMMENTS:
            gcode += linenumber() + '(Begin operation: ' + obj.Label + ')\n'
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        # Get coolant mode:
        coolantMode = 'None'  # None is the word returned from the operation
        if hasattr(obj, 'CoolantMode') or hasattr(obj, 'Base') and \
           hasattr(obj.Base, 'CoolantMode'):
            if hasattr(obj, 'CoolantMode'):
                coolantMode = obj.CoolantMode
            else:
                coolantMode = obj.Base.CoolantMode

        # Turn coolant on if required:
        if OUTPUT_COMMENTS:
            if not coolantMode == 'None':
                gcode += linenumber() + '(Coolant On:' + coolantMode + ')\n'
        if coolantMode == 'Flood':
            gcode += linenumber() + 'M8\n'
        if coolantMode == 'Mist':
            gcode += linenumber() + 'M7\n'

        # Parse the op:
        gcode += parse(obj)

        # Do the post_op:
        if OUTPUT_COMMENTS and OUTPUT_FINISH:
            gcode += linenumber() + '(Finish operation: ' + obj.Label + ')\n'
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

        # Turn coolant off if previously enabled:
        if not coolantMode == 'None':
            if OUTPUT_COMMENTS:
                gcode += linenumber() + '(Coolant Off:' + coolantMode + ')\n'
            gcode += linenumber() + 'M9\n'

    # Do the post_amble:
    if OUTPUT_BCNC:
        gcode += linenumber() + '(Block-name: post_amble)\n'
        gcode += linenumber() + '(Block-expand: 0)\n'
        gcode += linenumber() + '(Block-enable: 1)\n'
    if OUTPUT_COMMENTS:
        gcode += linenumber() + '(Begin postamble)\n'
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    # Optionally add a final XYZ position to the end of the gcode:
    if RETURN_TO:
        first_comma = RETURN_TO.find(',')
        last_comma = RETURN_TO.rfind(',')  # == first_comma if only one comma
        ref_X = ' X' + RETURN_TO[0:first_comma].strip()

        # Z is optional:
        if last_comma != first_comma:
            ref_Z = ' Z' + RETURN_TO[last_comma + 1:].strip()
            ref_Y = ' Y' + RETURN_TO[first_comma + 1:last_comma].strip()
        else:
            ref_Z = ''
            ref_Y = ' Y' + RETURN_TO[first_comma + 1:].strip()

        gcode += linenumber() + 'G0' + ref_X + ref_Y + ref_Z + '\n'

    # Optionally add recommended Marlin 2.x configuration to gcode file:
    if OUTPUT_MARLIN_CONFIG:
        gcode += linenumber() + '(Marlin 2.x Configuration)\n'
        gcode += linenumber() + '(The following should be enabled in)\n'
        gcode += linenumber() + '(the configuration files of Marlin 2.x)\n'
        gcode += linenumber() + '(#define ARC_SUPPORT)\n'
        gcode += linenumber() + '(#define CNC_COORDINATE_SYSTEMS)\n'
        gcode += linenumber() + '(#define PAREN_COMMENTS)\n'
        gcode += linenumber() + '(#define GCODE_MOTION_MODES)\n'
        gcode += linenumber() + '(#define G0_FEEDRATE)\n'
        gcode += linenumber() + '(define VARIABLE_G0_FEEDRATE)\n'

    # Show the gcode result dialog:
    if FreeCAD.GuiUp and SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print('Done postprocessing.')

    # Write the file:
    with open(filename, 'w') as fp:
        fp.write(final)
Example #20
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 #21
0
def export(objectslist, filename, argstring):
    processArguments(argstring)
    global UNITS
    global UNIT_FORMAT

    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

    print("postprocessing...")
    gcode = ""

    # write header
    if OUTPUT_HEADER:
        gcode += linenumber() + "(Exported by FreeCAD)\n"
        gcode += linenumber() + "(Post Processor: " + __name__ + ")\n"
        gcode += linenumber() + "(Output Time:" + str(now) + ")\n"

    # Write the preamble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(begin preamble)\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line
    gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:

        # fetch machine details
        job = PathUtils.findParentJob(obj)

        myMachine = 'not set'

        if hasattr(job, "MachineName"):
            myMachine = job.MachineName

        if hasattr(job, "MachineUnits"):
            if job.MachineUnits == "Metric":
                UNITS = "G21"
                UNIT_FORMAT = 'mm/min'
            else:
                UNITS = "G20"
                UNIT_FORMAT = 'in/min'

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(begin operation: %s)\n" % obj.Label
            gcode += linenumber() + "(machine: %s, %s)\n" % (myMachine,
                                                             UNIT_FORMAT)
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(finish operation: %s)\n" % obj.Label
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble

    if OUTPUT_COMMENTS:
        gcode += "(begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    if not filename == '-':
        gfile = pythonopen(filename, "wb")
        gfile.write(final)
        gfile.close()

    return final
Example #22
0
def export(objectslist, filename, argstring):
    if not processArguments(argstring):
        return None

    global UNITS
    global UNIT_FORMAT
    global UNIT_FEED_FORMAT
    global MOTION_MODE
    global SUPPRESS_COMMANDS

    print("Post Processor: " + __name__ + " postprocessing...")
    gcode = ""

    # Write header:
    if OUTPUT_HEADER:
        gcode += linenumber() + "(Exported by FreeCAD)\n"
        gcode += linenumber() + "(Post Processor: " + __name__
        gcode += ".py, version: " + Revised + ")\n"
        gcode += linenumber() + "(Output Time:" + str(datetime.now()) + ")\n"

    # Suppress drill-cycle commands:
    if TRANSLATE_DRILL_CYCLES:
        SUPPRESS_COMMANDS += ["G80", "G98", "G99"]

    # Write the preamble:
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(Begin preamble)\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line

    # Write these settings AFTER the preamble,
    # to prevent the preamble from changing these:
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(Default Configuration)\n"
    gcode += linenumber() + MOTION_MODE + "\n"
    gcode += linenumber() + UNITS + "\n"
    gcode += linenumber() + WORK_PLANE + "\n"

    for obj in objectslist:
        # Debug...
        # print('\n' + '*'*70 + '\n')
        # dump(obj)
        # print('\n' + '*'*70 + '\n')
        if not hasattr(obj, "Path"):
            print(
                "The object "
                + obj.Name
                + " is not a path. Please select only path and Compounds."
            )
            return

        # Skip inactive operations:
        if PathUtil.opProperty(obj, "Active") is False:
            continue

        # Do the pre_op:
        if OUTPUT_BCNC:
            gcode += linenumber() + "(Block-name: " + obj.Label + ")\n"
            gcode += linenumber() + "(Block-expand: 0)\n"
            gcode += linenumber() + "(Block-enable: 1)\n"
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(Begin operation: " + obj.Label + ")\n"
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        # Get coolant mode:
        coolantMode = "None"  # None is the word returned from the operation
        if (
            hasattr(obj, "CoolantMode")
            or hasattr(obj, "Base")
            and hasattr(obj.Base, "CoolantMode")
        ):
            if hasattr(obj, "CoolantMode"):
                coolantMode = obj.CoolantMode
            else:
                coolantMode = obj.Base.CoolantMode

        # Turn coolant on if required:
        if OUTPUT_COMMENTS:
            if not coolantMode == "None":
                gcode += linenumber() + "(Coolant On:" + coolantMode + ")\n"
        if coolantMode == "Flood":
            gcode += linenumber() + "M8\n"
        if coolantMode == "Mist":
            gcode += linenumber() + "M7\n"

        # Parse the op:
        gcode += parse(obj)

        # Do the post_op:
        if OUTPUT_COMMENTS and OUTPUT_FINISH:
            gcode += linenumber() + "(Finish operation: " + obj.Label + ")\n"
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

        # Turn coolant off if previously enabled:
        if not coolantMode == "None":
            if OUTPUT_COMMENTS:
                gcode += linenumber() + "(Coolant Off:" + coolantMode + ")\n"
            gcode += linenumber() + "M9\n"

    # Do the post_amble:
    if OUTPUT_BCNC:
        gcode += linenumber() + "(Block-name: post_amble)\n"
        gcode += linenumber() + "(Block-expand: 0)\n"
        gcode += linenumber() + "(Block-enable: 1)\n"
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(Begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    # Optionally add a final XYZ position to the end of the gcode:
    if RETURN_TO:
        first_comma = RETURN_TO.find(",")
        last_comma = RETURN_TO.rfind(",")  # == first_comma if only one comma
        ref_X = " X" + RETURN_TO[0:first_comma].strip()

        # Z is optional:
        if last_comma != first_comma:
            ref_Z = " Z" + RETURN_TO[last_comma + 1 :].strip()
            ref_Y = " Y" + RETURN_TO[first_comma + 1 : last_comma].strip()
        else:
            ref_Z = ""
            ref_Y = " Y" + RETURN_TO[first_comma + 1 :].strip()

        gcode += linenumber() + "G0" + ref_X + ref_Y + ref_Z + "\n"

    # Optionally add recommended Marlin 2.x configuration to gcode file:
    if OUTPUT_MARLIN_CONFIG:
        gcode += linenumber() + "(Marlin 2.x Configuration)\n"
        gcode += linenumber() + "(The following should be enabled in)\n"
        gcode += linenumber() + "(the configuration files of Marlin 2.x)\n"
        gcode += linenumber() + "(#define ARC_SUPPORT)\n"
        gcode += linenumber() + "(#define CNC_COORDINATE_SYSTEMS)\n"
        gcode += linenumber() + "(#define PAREN_COMMENTS)\n"
        gcode += linenumber() + "(#define GCODE_MOTION_MODES)\n"
        gcode += linenumber() + "(#define G0_FEEDRATE)\n"
        gcode += linenumber() + "(define VARIABLE_G0_FEEDRATE)\n"

    # Show the gcode result dialog:
    if FreeCAD.GuiUp and SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("Done postprocessing.")

    # Write the file:
    with open(filename, "w") as fp:
        fp.write(final)
Example #23
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 #24
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 #25
0
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()
Example #26
0
def export(objectslist, filename, argstring):

  if not processArguments(argstring):
    return None

  global UNITS
  global UNIT_FORMAT
  global UNIT_SPEED_FORMAT
  global MOTION_MODE
  global SUPPRESS_COMMANDS

  print("Post Processor: " + __name__ + " postprocessing...")
  gcode = ""

  # write header
  if OUTPUT_HEADER:
    gcode += linenumber() + "(Exported by FreeCAD)\n"
    gcode += linenumber() + "(Post Processor: " + __name__ + ")\n"
    gcode += linenumber() + "(Output Time:" + str(datetime.datetime.now()) + ")\n"

  # Check canned cycles for drilling
  if TRANSLATE_DRILL_CYCLES:
    if len(SUPPRESS_COMMANDS) == 0:
      SUPPRESS_COMMANDS = ['G99', 'G98', 'G80']
    else:
      SUPPRESS_COMMANDS += ['G99', 'G98', 'G80']

  # Write the preamble
  if OUTPUT_COMMENTS:
    gcode += linenumber() + "(Begin preamble)\n"
  for line in PREAMBLE.splitlines(True):
    gcode += linenumber() + line
  # verify if PREAMBLE have changed MOTION_MODE or UNITS
  if 'G90' in PREAMBLE:
    MOTION_MODE = 'G90'
  elif 'G91' in PREAMBLE:
    MOTION_MODE = 'G91'
  else:
    gcode += linenumber() + MOTION_MODE + "\n"
  if 'G21' in PREAMBLE:
    UNITS = 'G21'
    UNIT_FORMAT = 'mm'
    UNIT_SPEED_FORMAT = 'mm/min'
  elif 'G20' in PREAMBLE:
    UNITS = 'G20'
    UNIT_FORMAT = 'in'
    UNIT_SPEED_FORMAT = 'in/min'
  else:
    gcode += linenumber() + UNITS + "\n"

  for obj in objectslist:
    # Debug...
    # print("\n" + "*"*70)
    # dump(obj)
    # print("*"*70 + "\n")
    if not hasattr(obj, "Path"):
      print("The object " + obj.Name + " is not a path. Please select only path and Compounds.")
      return

    # Skip inactive operations
    if PathUtil.opProperty(obj, 'Active') is False:
        continue

    # do the pre_op
    if OUTPUT_BCNC:
      gcode += linenumber() + "(Block-name: " + obj.Label + ")\n"
      gcode += linenumber() + "(Block-expand: 0)\n"
      gcode += linenumber() + "(Block-enable: 1)\n"
    if OUTPUT_COMMENTS:
      gcode += linenumber() + "(Begin operation: " + obj.Label + ")\n"
    for line in PRE_OPERATION.splitlines(True):
      gcode += linenumber() + line

    # get coolant mode
    coolantMode = 'None'
    if hasattr(obj, "CoolantMode") or hasattr(obj, 'Base') and  hasattr(obj.Base, "CoolantMode"):
        if hasattr(obj, "CoolantMode"):
            coolantMode = obj.CoolantMode
        else:
            coolantMode = obj.Base.CoolantMode

    # turn coolant on if required
    if OUTPUT_COMMENTS:
        if not coolantMode == 'None':
            gcode += linenumber() + '(Coolant On:' + coolantMode + ')\n'
    if coolantMode == 'Flood':
        gcode  += linenumber() + 'M8' + '\n'
    if coolantMode == 'Mist':
        gcode += linenumber() + 'M7' + '\n'

    # Parse the op
    gcode += parse(obj)

    # do the post_op
    if OUTPUT_COMMENTS:
      gcode += linenumber() + "(Finish operation: " + obj.Label + ")\n"
    for line in POST_OPERATION.splitlines(True):
      gcode += linenumber() + line

    # turn coolant off if required
    if not coolantMode == 'None':
        if OUTPUT_COMMENTS:
            gcode += linenumber() + '(Coolant Off:' + coolantMode + ')\n'
        gcode += linenumber() +'M9' + '\n'

  # do the post_amble
  if OUTPUT_BCNC:
    gcode += linenumber() + "(Block-name: post_amble)\n"
    gcode += linenumber() + "(Block-expand: 0)\n"
    gcode += linenumber() + "(Block-enable: 1)\n"
  if OUTPUT_COMMENTS:
    gcode += linenumber() + "(Begin postamble)\n"
  for line in POSTAMBLE.splitlines(True):
    gcode += linenumber() + line

  if RETURN_TO:
    gcode += linenumber() + "G0 X%s Y%s" % tuple(RETURN_TO)

  # show the gCode result dialog
  if FreeCAD.GuiUp and SHOW_EDITOR:
    dia = PostUtils.GCodeEditorDialog()
    dia.editor.setText(gcode)
    result = dia.exec_()
    if result:
      final = dia.editor.toPlainText()
    else:
      final = gcode
  else:
    final = gcode

  print("Done postprocessing.")

  # write the file
  gfile = pythonopen(filename, "w")
  gfile.write(final)
  gfile.close()
Example #27
0
def export(objectslist, filename, argstring):
    global OUTPUT_COMMENTS
    global OUTPUT_HEADER
    global SHOW_EDITOR
    global CurrentState
    global GetValue

    for arg in argstring.split():
        if arg == '--comments':
            OUTPUT_COMMENTS = True
        if arg == '--inches':
            GetValue = getImperialValue
        if arg == '--no-header':
            OUTPUT_HEADER = False
        if arg == '--no-show-editor':
            SHOW_EDITOR = False

    for obj in objectslist:
        if not hasattr(obj, "Path"):
            s = "the object " + obj.Name
            s += " is not a path. Please select only path and Compounds."
            print(s)
            return

    CurrentState = {
        'X': 0,
        'Y': 0,
        'Z': 0,
        'F': 0,
        'S': 0,
        'JSXY': 0,
        'JSZ': 0,
        'MSXY': 0,
        'MSZ': 0
    }
    print("postprocessing...")
    gcode = ""

    # write header
    if OUTPUT_HEADER:
        gcode += linenumber() + "'Exported by FreeCAD\n"
        gcode += linenumber() + "'Post Processor: " + __name__ + "\n"
        gcode += linenumber() + "'Output Time:" + str(now) + "\n"

    # Write the preamble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(begin preamble)\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line

    for obj in objectslist:

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(begin operation: " + obj.Label + ")\n"
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(finish operation: " + obj.Label + ")\n"
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble
    if OUTPUT_COMMENTS:
        gcode += "(begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    # Write the output
    gfile = pythonopen(filename, "wb")
    gfile.write(final)
    gfile.close()
Example #28
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()
Example #29
0
def export(objectslist, filename, argstring):
    if not processArguments(argstring):
        return None
    global UNITS
    global UNIT_FORMAT
    global UNIT_SPEED_FORMAT

    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 None

    print("postprocessing...")
    gcode = ""

    # write header
    if OUTPUT_HEADER:
        gcode += linenumber() + "(Exported by FreeCAD)\n"
        gcode += linenumber() + "(Post Processor: " + __name__ + ")\n"
        gcode += linenumber() + "(Output Time:" + str(now) + ")\n"

    # Write the preamble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(begin preamble)\n"
    for line in PREAMBLE.splitlines(False):
        gcode += linenumber() + line + "\n"
    gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(begin operation: %s)\n" % obj.Label
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(finish operation: %s)\n" % obj.Label
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble
    if OUTPUT_COMMENTS:
        gcode += "(begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    if FreeCAD.GuiUp and SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    if not filename == '-':
        gfile = pythonopen(filename, "wb")
        gfile.write(final)
        gfile.close()

    return final
Example #30
0
def export(objectslist, filename, argstring):
    # pylint: disable=unused-argument
    if not processArguments(argstring):
        return None
    global UNITS
    global UNIT_FORMAT
    global UNIT_SPEED_FORMAT

    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

    print("postprocessing...")
    gcode = ""

    # Find the machine.
    # The user my have overridden post processor defaults in the GUI.  Make sure we're using the current values in the Machine Def.
    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("No machine found in this selection")

    # write header
    if OUTPUT_HEADER:
        gcode += linenumber() + "(Exported by FreeCAD)\n"
        gcode += linenumber() + "(Post Processor: " + __name__ + ")\n"
        gcode += linenumber() + "(Output Time:" + str(now) + ")\n"

    # Write the preamble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(begin preamble)\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line
    gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(begin operation: " + obj.Label + ")\n"
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(finish operation: " + obj.Label + ")\n"
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble

    if OUTPUT_COMMENTS:
        gcode += "(begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    print('show editor: {}'.format(SHOW_EDITOR))
    if FreeCAD.GuiUp and SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    gfile = pythonopen(filename, "w")
    gfile.write(final)
    gfile.close()
Example #31
0
def export(objectslist, filename, argstring):

    if not processArguments(argstring):
        return None

    global UNITS
    global UNIT_FORMAT
    global UNIT_SPEED_FORMAT
    global MOTION_MODE

    print("Post Processor: " + __name__ + " postprocessing...")
    gcode = ""

    # write header
    if OUTPUT_HEADER:
        gcode += linenumber() + "(Exported by FreeCAD)\n"
        gcode += linenumber() + "(Post Processor: " + __name__ + ")\n"
        gcode += linenumber() + "(Output Time:" + str(
            datetime.datetime.now()) + ")\n"

    # Write the preamble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(begin preamble)\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line
    # verify if PREAMBLE have changed MOTION_MODE or UNITS
    if 'G90' in PREAMBLE:
        MOTION_MODE = 'G90'
    elif 'G91' in PREAMBLE:
        MOTION_MODE = 'G91'
    else:
        gcode += linenumber() + MOTION_MODE + "\n"
    if 'G21' in PREAMBLE:
        UNITS = 'G21'
        UNIT_FORMAT = 'mm'
        UNIT_SPEED_FORMAT = 'mm/min'
    elif 'G20' in PREAMBLE:
        UNITS = 'G20'
        UNIT_FORMAT = 'in'
        UNIT_SPEED_FORMAT = 'in/min'
    else:
        gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:
        # Debug...
        # print("\n" + "*"*70)
        # dump(obj)
        # print("*"*70 + "\n")
        if not hasattr(obj, "Path"):
            print("The object " + obj.Name +
                  " is not a path. Please select only path and Compounds.")
            return

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(begin operation: " + obj.Label + ")\n"
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        # Parse the op
        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(finish operation: " + obj.Label + ")\n"
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    # show the gCode result dialog
    if FreeCAD.GuiUp and SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    # write the file
    gfile = pythonopen(filename, "w")
    gfile.write(final)
    gfile.close()
Example #32
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()
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 #34
0
def export(objectslist, filename, argstring):
    # pylint: disable=global-statement
    processArguments(argstring)
    for i in objectslist:
        print(i.Name)
    global UNITS
    global UNIT_FORMAT

    print("postprocessing...")
    gcode = ""

    # write header
    if OUTPUT_HEADER:
        gcode += HEADER

    gcode += SAFETYBLOCK

    # Write the preamble
    if OUTPUT_COMMENTS:
        for item in objectslist:
            if isinstance(item.Proxy,
                          PathScripts.PathToolController.ToolController):
                gcode += ";T{}={}\n".format(item.ToolNumber, item.Name)
        gcode += linenumber() + ";begin preamble\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line

    gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:
        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + ";begin operation\n"
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + ";end operation: %s\n" % obj.Label
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble

    if OUTPUT_COMMENTS:
        gcode += ";begin postamble\n"
    for line in TOOLRETURN.splitlines(True):
        gcode += linenumber() + line
    for line in SAFETYBLOCK.splitlines(True):
        gcode += linenumber() + line
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    if not filename == '-':
        gfile = pythonopen(filename, "w")
        gfile.write(final)
        gfile.close()

    return final
Example #35
0
def export(objectslist, filename, argstring):
    processArguments(argstring)
    global UNITS
    global IP_ADDR
    for obj in objectslist:
        if not hasattr(obj, "Path"):
            FreeCAD.Console.PrintError("the object " + obj.Name + " is not a path. Please select only path and Compounds.\n")
            return

    FreeCAD.Console.PrintMessage("postprocessing...\n")
    gcode = ""

    # Find the machine.
    # The user my have overridden post processor defaults in the GUI.  Make
    # sure we're using the current values in the Machine Def.
    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:
        FreeCAD.Console.PrintWarning("No machine found in this selection\n")

    # write header
    if OUTPUT_HEADER:
        gcode += linenumber() + "(Exported by FreeCAD)\n"
        gcode += linenumber() + "(Post Processor: " + __name__ + ")\n"
        gcode += linenumber() + "(Output Time:" + str(now) + ")\n"

    # Write the preamble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + "(begin preamble)\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line
    gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(begin operation: " + obj.Label + ")\n"
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(finish operation: " + obj.Label + ")\n"
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble

    if OUTPUT_COMMENTS:
        gcode += "(begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    if IP_ADDR is not None:
        sendToSmoothie(IP_ADDR, final, filename)
    else:

        if not filename == '-':
            gfile = pythonopen(filename, "wb")
            gfile.write(final)
            gfile.close()

    FreeCAD.Console.PrintMessage("done postprocessing.\n")
    return final
Example #36
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 #37
0
def export(objectslist, filename, args):
    global UNITS
    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

    print "postprocessing..."
    gcode = ""

    #Find the machine.
    #The user my have overridden post processor defaults in the GUI.  Make sure we're using the current values in the Machine Def.
    myMachine = None
    for pathobj in objectslist:
        if hasattr(pathobj, "Group"):  #We have a compound or project.
            for p in pathobj.Group:
                if p.Name == "Machine":
                    myMachine = p
    if myMachine is None:
        print "No machine found in this project"
    else:
        if myMachine.MachineUnits == "Metric":
            UNITS = "G21"
        else:
            UNITS = "G20"

    # write header
    if OUTPUT_HEADER:
        gcode += linenumber() + "(Exported by FreeCAD)\n"
        gcode += linenumber() + "(Post Processor: " + __name__ + ")\n"
        gcode += linenumber() + "(Output Time:" + str(now) + ")\n"

    #Write the preamble
    if OUTPUT_COMMENTS: gcode += linenumber() + "(begin preamble)\n"
    for line in PREAMBLE.splitlines(True):
        gcode += linenumber() + line
    gcode += linenumber() + UNITS + "\n"

    for obj in objectslist:

        #do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(begin operation: " + obj.Label + ")\n"
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        #do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + "(finish operation: " + obj.Label + ")\n"
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    #do the post_amble

    if OUTPUT_COMMENTS: gcode += "(begin postamble)\n"
    for line in POSTAMBLE.splitlines(True):
        gcode += linenumber() + line

    if SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print "done postprocessing."

    gfile = pythonopen(filename, "wb")
    gfile.write(gcode)
    gfile.close()
Example #38
0
def export(objectslist, filename, argstring):
    if not processArguments(argstring):
        return None
    global UNITS
    global UNIT_FORMAT
    global UNIT_SPEED_FORMAT

    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 None

    print("postprocessing...")
    gcode = linenumber() + 'IMF_PBL_V1.0\n'

    # write header
    now = datetime.datetime.now()
    gcode += linenumber() + ";- Exported by FreeCAD\n"
    gcode += linenumber() + ";- Post Processor: " + __name__ + '\n'
    gcode += linenumber() + ";- Output Time:" + str(now) + '\n'

    # Write the preamble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + ";- begin preamble\n"
    for line in PREAMBLE.splitlines(False):
        gcode += linenumber() + line + '\n'
    if OUTPUT_COMMENTS:
        gcode += linenumber() + ";- finish preamble\n"

    for obj in objectslist:

        # fetch machine details
        job = PathUtils.findParentJob(obj)

        myMachine = job.Machine if hasattr(job, 'Machine') else MACHINE_NAME

        # FIXME: we only operate using ISEL units (µm and µm/s)
        if hasattr(job, "MachineUnits"):
            print("Unknown parameter 'MachineUnits: "
                  "{}".format(job.MachineUnits))

        # do the pre_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + ";- begin operation: %s\n" % obj.Label
            gcode += linenumber() + ";- machine: %s\n" % myMachine
            gcode += linenumber() + ";- unit system: %s\n" % UNIT_SPEED_FORMAT
        for line in PRE_OPERATION.splitlines(True):
            gcode += linenumber() + line

        gcode += parse(obj)

        # do the post_op
        if OUTPUT_COMMENTS:
            gcode += linenumber() + ";- finish operation: %s\n" % obj.Label
        for line in POST_OPERATION.splitlines(True):
            gcode += linenumber() + line

    # do the post_amble
    if OUTPUT_COMMENTS:
        gcode += linenumber() + ";- begin postamble\n"
    for line in POSTAMBLE.splitlines(False):
        gcode += linenumber() + line + '\n'
    if OUTPUT_COMMENTS:
        gcode += linenumber() + ";- finish postamble\n"

    if FreeCAD.GuiUp and SHOW_EDITOR:
        dia = PostUtils.GCodeEditorDialog()
        dia.editor.setText(gcode)
        result = dia.exec_()
        if result:
            final = dia.editor.toPlainText()
        else:
            final = gcode
    else:
        final = gcode

    print("done postprocessing.")

    if not filename == '-':
        # Clear read-only flag set by Isel Remote
        try:
            chmod(filename, S_IWRITE | S_IREAD)
        except:
            pass  # file did not exist ?
        with pythonopen(filename, "w") as f:
            f.write(final)

    return final