[gcode_macro VORON_PURGE]
description: A purge macro that adapts to be near your actual printed objects
gcode:
    # Get relevant printer params
    {% set travel_speed = (printer.toolhead.max_velocity) * 60 | float %}
    {% set cross_section = printer.configfile.settings.extruder.max_extrude_cross_section | float %}
    
    # Use firmware retraction if it is defined
    {% if printer.firmware_retraction is defined %}
        {% set RETRACT = G10 | string %}
        {% set UNRETRACT = G11 | string %}
    {% else %}
        {% set RETRACT = 'G1 E-.5 F2100' | string %}
        {% set UNRETRACT = 'G1 E.5 F2100' | string %}
    {% endif %}

    # Get purge settings from _Kamp_Settings
    {% set kamp_settings = printer["gcode_macro _KAMP_Settings"] %}
    {% set verbose_enable = kamp_settings.verbose_enable | abs %}
    {% set purge_height = kamp_settings.purge_height | float %}
    {% set tip_distance = kamp_settings.tip_distance | float %}
    {% set purge_margin = kamp_settings.purge_margin | float %}
    {% set purge_amount = kamp_settings.purge_amount | float %}
    {% set flow_rate = kamp_settings.flow_rate | float %}
    {% set size = 10 | float %}

    # Calculate purge origins and centers from objects
    {% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %}    # Get all object points
    {% set purge_x_min = (all_points | map(attribute=0) | min | default(0)) %}                          # Object x min
    {% set purge_x_max = (all_points | map(attribute=0) | max | default(0)) %}                          # Object x max
    {% set purge_y_min = (all_points | map(attribute=1) | min | default(0)) %}                          # Object y min
    {% set purge_y_max = (all_points | map(attribute=1) | max | default(0)) %}                          # Object y max

    {% set purge_x_center = ([((purge_x_max + purge_x_min) / 2) - (purge_amount / 2), 0] | max) %}      # Create center point of purge line relative to print on X axis
    {% set purge_y_center = ([((purge_y_max + purge_y_min) / 2) - (purge_amount / 2), 0] | max) %}      # Create center point of purge line relative to print on Y axis

    {% set purge_x_origin = ([purge_x_min - purge_margin, 0] | max) %}                                  # Add margin to x min, compare to 0, and choose the larger
    {% set purge_y_origin = ([purge_y_min - purge_margin, 0] | max) %}                                  # Add margin to y min, compare to 0, and choose the larger

    # Calculate purge speed
    {% set purge_move_speed = (flow_rate / 5.0) * 60 | float %}

    {% if cross_section < 5 %}

        {action_respond_info("[Extruder] max_extrude_cross_section is insufficient for purge, please set it to 5 or greater. Purge skipped.")}

    {% else %}

        {% if verbose_enable == True %}

        {action_respond_info("Moving filament tip {}mms".format(                                                                 
            (tip_distance),                                                                                      
        )) }
        {% endif %}

        {% if printer.firmware_retraction is defined %}
            {action_respond_info("KAMP purge is using firmware retraction.")}
        {% else %}
            {action_respond_info("KAMP purge is not using firmware retraction, it is recommended to configure it.")}
        {% endif %}

            SAVE_GCODE_STATE NAME=Prepurge_State                                                            # Create gcode state

            G92 E0                                                                                          # Reset extruder
            G0 F{travel_speed}                                                                              # Set travel speed
            G90                                                                                             # Absolute positioning
            G0 X{purge_x_origin} Y{purge_y_origin+size/2}                                                   # Move to purge position
            G0 Z{purge_height}                                                                              # Move to purge Z height
            M83                                                                                             # Relative extrusion mode
            G1 E{tip_distance} F{purge_move_speed}                                                          # Move tip of filament to nozzle
            G1 X{purge_x_origin+size*0.289} Y{purge_y_origin+size} E{purge_amount/4} F{purge_move_speed}    # Purge first line of logo
            {RETRACT}                                                                                       # Retract
            G0 Z{purge_height*2}                                                                            # Z hop
            G0 X{purge_x_origin+size*0.789} Y{purge_y_origin+size}                                          # Move to second purge line origin
            G0 Z{purge_height}                                                                              # Move to purge Z height
            {UNRETRACT}                                                                                     # Recover
            G1 X{purge_x_origin+size*0.211} Y{purge_y_origin} E{purge_amount/2} F{purge_move_speed}         # Purge second line of logo
            {RETRACT}                                                                                       # Retract
            G0 Z{purge_height*2}                                                                            # Z hop
            G0 X{purge_x_origin+size*0.711} Y{purge_y_origin}                                               # Move to third purge line origin
            G0 Z{purge_height}                                                                              # Move to purge Z height
            {UNRETRACT}                                                                                     # Recover
            G1 X{purge_x_origin+size} Y{purge_y_origin+size/2}  E{purge_amount/4} F{purge_move_speed}       # Purge third line of logo
            {RETRACT}                                                                                       # Retract
            G92 E0                                                                                          # Reset extruder distance
            M82                                                                                             # Absolute extrusion mode
            G0 Z{purge_height*2} F{travel_speed}                                                            # Z hop

            RESTORE_GCODE_STATE NAME=Prepurge_State                                                         # Restore gcode state

    {% endif %}