FlashPrint Raft Postprocessor

2018

FlashPrint Raft Postprocessor

Was having some bed adhesion issues for a model and tried to enable rafts in FlashPrint 3.24.0

Enabling the "Space to Model (z)" option only appeared to work for the first layer.

Example of the output (with a very high value of 0.40mm)

Had many emails back and forth with support but didn't get anywhere, but I was also writing a really basic post processor to fix the bug myself.

(Additionally found the default gcode uses a 0.13mm layer height for the first couple of layers rather than the correct 0.12mm. But this could just be tweaks for adhesion/quality)

fp_fix_raft_gcode.python


import re

PROGRAM_NAME = 'fp_fix_raft_gcode'
PROGRAM_VERSION = 0.1

def fix_raft_gcode(filename: str, offset: float=0.10, layer_height: float=0.12):
    """
    FlashPrint 3.24.0 ignores the raft Z offset for layers >= 2
    This function takes a .gx file, applies a new Z offset and updates the Z heights for all layers

    Layer height should match what has been set in FlashPrint  (does not detect  different layer heights for layer 1)

    The gcode generated by FlashPrint also changes the layer height for the first few layers for some reason  (with a
    12mm layer height the first few are set to 13mm).  This scripts removes that change (for better or worse)
    """

    output = [
        '; File post processed by {} v{}\n'.format(PROGRAM_NAME, PROGRAM_VERSION),
        '; New raft z offset {}mm with {}mm layer height\n'.format(offset, layer_height)
    ]

    state_in_raft = True
    state_past_second_layer = False
    raft_height = None
    last_z = None

    # layer that we are on
    counter = 0

    with open(filename, 'rb') as f:
        f.readline()  # skip header
        f.readline()  # skip binary image
        for line in f:
            line = line.decode('utf8')

            # raft is over, so record the last z height.  This is the top of the raft
            if ';shell' in line:
                if state_in_raft:
                    state_in_raft = False
                    raft_height = last_z
                    print('Raft over, height is: {}'.format(raft_height))

            # is there a z move?
            match = re.match('N(\d+) G1 Z(.*?) F(\d+)', line)

            if match is not None:
                last_z = float(match.group(2))

                # Are we past the raft?  If so we recalculate the new z height
                if not state_in_raft:

                    # the 2nd layer has a weird z adjust that does nothing
                    # (except trip us up by thinking there is an extra layer)
                    if counter == 2 and state_past_second_layer is False:
                        counter -= 1
                        state_past_second_layer = True

                    new_z = raft_height + offset + (counter * layer_height)
                    counter += 1

                    # overwrite the current line with the new z move
                    line = 'N{} G1 Z{:0.2f} F{}\n'.format(match.group(1), new_z, match.group(3))
                    print('old_z:{:0.2f} new_z:{:0.2f}  ->  {}'.format(last_z, new_z, line.strip()))

            output.append(line)
    return output

def main(src_filename: str, dest_filename: str, offset: float=0.20, layer_height: float=0.12):
    lines = fix_raft_gcode(src_filename, offset, layer_height)

    with open(dest_filename, 'w+') as f:
        f.writelines(lines)

    print('Saved {} lines'.format(len(lines)))

if __name__ == '__main__':
    src = r'R:\3D Printing\Models\16_keys_Macropad\Plate.gx'
    dest = r'R:\3D Printing\Models\16_keys_Macropad\Plate.fixed.10_z_offset.g'
    main(src, dest, 0.12, 0.12)