From da75f1deda67a8c14fbad83d7d743c7b2032c1fd Mon Sep 17 00:00:00 2001 From: elpopo <68954733+elpopo-eng@users.noreply.github.com> Date: Sat, 24 Feb 2024 11:35:22 +0100 Subject: [PATCH 1/5] Update primeline so that it runs along the rectangle of the first layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to fbeauKmi Co-Authored-By: Frédéric Beaucamp <88246672+fbeauKmi@users.noreply.github.com> --- macros/helpers/prime_line.cfg | 20 ++++++++++++++++++-- user_templates/variables.cfg | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index baa83e2df..e12f485f2 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -30,6 +30,19 @@ gcode: {% set prime_line_y = params.START_Y|default(prime_line_y)|float %} {% set prime_line_direction = params.LINE_DIRECTION|default(printer["gcode_macro _USER_VARIABLES"].prime_line_direction)|string|upper %} + # Redefine start position from fl_size + {% set fl_size=printer['gcode_macro START_PRINT'].fl_size %} + {% if fl_size != "0_0_0_0" %} + {% set prime_line_margin = params.LINE_MARGIN|default(printer["gcode_macro _USER_VARIABLES"].prime_line_margin|float) %} + {% set min_x, min_y, max_x, max_y = fl_size.split("_")|map('float') %} + {% set prime_line_x = [[prime_line_x, min_x - prime_line_margin] | max, max_x + prime_line_margin] | min %} + {% set prime_line_y = [[prime_line_y, min_y - prime_line_margin] | max, max_y + prime_line_margin] | min %} + {% endif %} + + {% set axes_max = printer.toolhead.axis_maximum %} + {% set prime_line_way = -1 if (prime_line_direction == "X" and prime_line_x > axes_max.x/2) or (prime_line_direction == "Y" and prime_line_y > axes_max.y/2) else 1 %} + + {% if verbose %} {action_respond_info("Prime line length: %.4f" % prime_line_length)} {action_respond_info("Prime line eight: %.4f" % prime_line_height)} @@ -92,10 +105,12 @@ gcode: # Prime line G92 E0 + {% if prime_line_direction == "X" %} - G1 X{prime_line_x + prime_line_length} E{prime_line_purge_distance} F{speed} + G1 X{prime_line_x + prime_line_way*prime_line_length} E{prime_line_purge_distance} F{speed} {% elif prime_line_direction == "Y" %} - G1 Y{prime_line_y + prime_line_length} E{prime_line_purge_distance} F{speed} + G1 Y{prime_line_y + prime_line_way*prime_line_length} E{prime_line_purge_distance} F{speed} + {% else %} { action_respond_error("Prime line direction is not valid. Choose either X or Y in the variables.cfg file!") } {% endif %} @@ -116,3 +131,4 @@ gcode: {% if filament_sensor_enabled and re_enable_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% endif %} + \ No newline at end of file diff --git a/user_templates/variables.cfg b/user_templates/variables.cfg index 817d621df..63c9b1390 100644 --- a/user_templates/variables.cfg +++ b/user_templates/variables.cfg @@ -61,6 +61,7 @@ variable_prime_line_length: 40 # length of the prime line on the bed (in mm) variable_prime_line_purge_distance: 30 # length of filament to purge (in mm) variable_prime_line_flowrate: 10 # mm3/s used for the prime line variable_prime_line_height: 0.6 # mm, used for actual cross section computation +variable_prime_line_margin: 5 # distance of purge line from fl_size rectangle ## Park position used when pause, end_print, etc... variable_park_position_xy: -1, -1 From 0870c2fddd422bb03d02d7110f89f8f5ce0b2470 Mon Sep 17 00:00:00 2001 From: elpopo <68954733+elpopo-eng@users.noreply.github.com> Date: Sat, 24 Feb 2024 16:07:31 +0100 Subject: [PATCH 2/5] Add default prime_line_margin --- macros/helpers/prime_line.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index e12f485f2..2284c299d 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -33,7 +33,8 @@ gcode: # Redefine start position from fl_size {% set fl_size=printer['gcode_macro START_PRINT'].fl_size %} {% if fl_size != "0_0_0_0" %} - {% set prime_line_margin = params.LINE_MARGIN|default(printer["gcode_macro _USER_VARIABLES"].prime_line_margin|float) %} + {% set prime_line_margin = printer["gcode_macro _USER_VARIABLES"].prime_line_margin|default(5.0|float) %} + {% set prime_line_margin = params.LINE_MARGIN|default(prime_line_margin|float) %} {% set min_x, min_y, max_x, max_y = fl_size.split("_")|map('float') %} {% set prime_line_x = [[prime_line_x, min_x - prime_line_margin] | max, max_x + prime_line_margin] | min %} {% set prime_line_y = [[prime_line_y, min_y - prime_line_margin] | max, max_y + prime_line_margin] | min %} From 97476678e3e01f0dc5ad386bacb85af888d6fcc9 Mon Sep 17 00:00:00 2001 From: elpopo <68954733+elpopo-eng@users.noreply.github.com> Date: Sun, 25 Feb 2024 10:23:15 +0100 Subject: [PATCH 3/5] Update prime_line.cfg --- macros/helpers/prime_line.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index 2284c299d..46e90aa1f 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -33,7 +33,7 @@ gcode: # Redefine start position from fl_size {% set fl_size=printer['gcode_macro START_PRINT'].fl_size %} {% if fl_size != "0_0_0_0" %} - {% set prime_line_margin = printer["gcode_macro _USER_VARIABLES"].prime_line_margin|default(5.0|float) %} + {% set prime_line_margin = printer["gcode_macro _USER_VARIABLES"].prime_line_margin|default(5.0)|float %} {% set prime_line_margin = params.LINE_MARGIN|default(prime_line_margin|float) %} {% set min_x, min_y, max_x, max_y = fl_size.split("_")|map('float') %} {% set prime_line_x = [[prime_line_x, min_x - prime_line_margin] | max, max_x + prime_line_margin] | min %} From 4a1d799671e62ea04020ba264fb835247cf9223b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Mon, 26 Feb 2024 22:13:30 +0000 Subject: [PATCH 4/5] more flexible adaptive primeline --- macros/base/start_print.cfg | 13 +++++- macros/helpers/prime_line.cfg | 78 +++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index e98859a1c..29a9a05d1 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -29,6 +29,7 @@ gcode: {% set TOOLS_USED = params.TOOLS_USED|default("")|string %} # Check if MMU gates (used in gcode file) are availables {% set SYNC_MMU_EXTRUDER = params.SYNC_MMU_EXTRUDER|default(0)|int %} # set MMU gear motor and extruder synchronization during print TODO {% set BED_MESH_PROFILE = params.MESH|default("")|string %} # Bed mesh profile to load + {% set ADAPTIVE_PRIMELINE = params.ADAPTIVE_PRIMELINE|default(True) %} # Weither to do or not an adaptive prime line near the real print zone # Set the variables to be used in all the modules based on the slicer parameters SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=bed_temp VALUE={BED_TEMP} @@ -43,6 +44,7 @@ gcode: SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=material VALUE='"{MATERIAL}"' SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=fl_size VALUE='"{FL_SIZE}"' SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=bed_mesh_profile VALUE='"{BED_MESH_PROFILE}"' + SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=adaptive_primeline VALUE={ADAPTIVE_PRIMELINE} {% if params.TOTAL_LAYER %} # total layers count (if provided by the slicer) SET_PRINT_STATS_INFO TOTAL_LAYER={params.TOTAL_LAYER|int} @@ -193,7 +195,15 @@ gcode: [gcode_macro _MODULE_PRIMELINE] gcode: - PRIMELINE + # ----- PRIME LINE ------------------------------------------- + {% set FL_SIZE = printer["gcode_macro START_PRINT"].fl_size %} + {% set ADAPTIVE_PRIMELINE = printer["gcode_macro START_PRINT"].adaptive_primeline %} + {% set verbose = printer["gcode_macro _USER_VARIABLES"].verbose %} + + {% if verbose %} + RESPOND MSG="Executing a primeline..." + {% endif %} + PRIMELINE SIZE={FL_SIZE} ADAPTIVE_MODE={ADAPTIVE_PRIMELINE} [gcode_macro _MODULE_HEATSOAK_BED] @@ -398,7 +408,6 @@ gcode: {% if verbose %} RESPOND MSG="Bed mesh measurement..." {% endif %} - ADAPTIVE_BED_MESH SIZE={FL_SIZE} {% else %} {% if verbose %} diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index 46e90aa1f..9e32011ba 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -1,18 +1,46 @@ [gcode_macro PRIMELINE] gcode: - # Macro parameters + # Base macro parameters {% set prime_line_length = params.LINE_LENGTH|default(printer["gcode_macro _USER_VARIABLES"].prime_line_length)|float %} {% set prime_line_purge_distance = params.PURGE_LENGTH|default(printer["gcode_macro _USER_VARIABLES"].prime_line_purge_distance)|float %} {% set prime_line_flowrate = params.FLOWRATE|default(printer["gcode_macro _USER_VARIABLES"].prime_line_flowrate)|float %} - {% if printer["gcode_macro _USER_VARIABLES"].prime_line_height %} - {% set prime_line_height = params.LINE_HEIGHT|default(printer["gcode_macro _USER_VARIABLES"].prime_line_height)|float %} - {% else %} - {% set prime_line_height = params.LINE_HEIGHT|default(0.6)|float %} + {% set prime_line_height = params.LINE_HEIGHT|default(printer["gcode_macro _USER_VARIABLES"].prime_line_height)|default(0.6)|float %} + {% set prime_line_adaptive = params.ADAPTIVE_MODE|default(True) %} + + # If the SIZE parameter is defined and not a dummy placeholder, we use it to do the adaptive bed mesh logic + {% set coordinatesFound = false %} + {% if params.SIZE is defined and params.SIZE != "0_0_0_0" %} + {% set xMinSpec, yMinSpec, xMaxSpec, yMaxSpec = params.SIZE.split('_')|map('trim')|map('int') %} + {% set coordinatesFound = true %} + {% elif printer.exclude_object is defined %} + {% if printer.exclude_object.objects %} + # Else if SIZE is not defined, we fallback to use the [exclude_object] tags + # This method is derived from Kyleisah KAMP repository: https://github.com/kyleisah/Klipper-Adaptive-Meshing-Purging) + {% set eo_points = printer.exclude_object.objects|map(attribute='polygon')|sum(start=[]) %} + {% set xMinSpec = eo_points|map(attribute=0)|min %} + {% set yMinSpec = eo_points|map(attribute=1)|min %} + {% set xMaxSpec = eo_points|map(attribute=0)|max %} + {% set yMaxSpec = eo_points|map(attribute=1)|max %} + {% set coordinatesFound = true %} + {% endif %} {% endif %} - # Set internal macro vars + # We get the default prime line position parameters {% set prime_line_x, prime_line_y = printer["gcode_macro _USER_VARIABLES"].prime_line_xy|map('float') %} - {% set prime_line_direction = printer["gcode_macro _USER_VARIABLES"].prime_line_direction|string|upper %} + {% set prime_line_x = params.START_X|default(prime_line_x)|float %} + {% set prime_line_y = params.START_Y|default(prime_line_y)|float %} + {% set prime_line_direction = params.LINE_DIRECTION|default(printer["gcode_macro _USER_VARIABLES"].prime_line_direction)|string|upper %} + + # If first layer is retrieved and adaptive mode is enabled, then we replace the coordinates to do an adaptive purge + {% if coordinatesFound and prime_line_adaptive %} + {% set prime_line_margin = params.LINE_MARGIN|default(printer["gcode_macro _USER_VARIABLES"].prime_line_margin)|default(5.0)|float %} + {% set prime_line_x = [[prime_line_x, xMinSpec - prime_line_margin]|max, xMaxSpec + prime_line_margin]|min %} + {% set prime_line_y = [[prime_line_y, yMinSpec - prime_line_margin]|max, yMaxSpec + prime_line_margin]|min %} + {% endif %} + + # Choose the way of printing the primeline (in + or -) alongside the direction to avoid going outside the bed boundaries + {% set axes_max = printer.toolhead.axis_maximum %} + {% set prime_line_way = -1 if (prime_line_direction == "X" and prime_line_x > axes_max.x/2) or (prime_line_direction == "Y" and prime_line_y > axes_max.y/2) else 1 %} {% set St = printer["gcode_macro _USER_VARIABLES"].travel_speed * 60 %} {% set Sz = printer["gcode_macro _USER_VARIABLES"].z_drop_speed * 60 %} @@ -25,31 +53,6 @@ gcode: {% set max_extrude_cross_section = printer["configfile"].config["extruder"]["max_extrude_cross_section"]|float %} {% set filament_diameter = printer["configfile"].config["extruder"]["filament_diameter"]|float %} - # some more Macro parameters after retrieving defaults - {% set prime_line_x = params.START_X|default(prime_line_x)|float %} - {% set prime_line_y = params.START_Y|default(prime_line_y)|float %} - {% set prime_line_direction = params.LINE_DIRECTION|default(printer["gcode_macro _USER_VARIABLES"].prime_line_direction)|string|upper %} - - # Redefine start position from fl_size - {% set fl_size=printer['gcode_macro START_PRINT'].fl_size %} - {% if fl_size != "0_0_0_0" %} - {% set prime_line_margin = printer["gcode_macro _USER_VARIABLES"].prime_line_margin|default(5.0)|float %} - {% set prime_line_margin = params.LINE_MARGIN|default(prime_line_margin|float) %} - {% set min_x, min_y, max_x, max_y = fl_size.split("_")|map('float') %} - {% set prime_line_x = [[prime_line_x, min_x - prime_line_margin] | max, max_x + prime_line_margin] | min %} - {% set prime_line_y = [[prime_line_y, min_y - prime_line_margin] | max, max_y + prime_line_margin] | min %} - {% endif %} - - {% set axes_max = printer.toolhead.axis_maximum %} - {% set prime_line_way = -1 if (prime_line_direction == "X" and prime_line_x > axes_max.x/2) or (prime_line_direction == "Y" and prime_line_y > axes_max.y/2) else 1 %} - - - {% if verbose %} - {action_respond_info("Prime line length: %.4f" % prime_line_length)} - {action_respond_info("Prime line eight: %.4f" % prime_line_height)} - {action_respond_info("prime line extrusion length: %4.f" % prime_line_purge_distance)} - {% endif %} - # We first compute the width of the prime line {% set purge_volume = prime_line_purge_distance * 3.14159 * (filament_diameter / 2)**2 %} {% set line_width = purge_volume / (prime_line_height * prime_line_length) %} @@ -71,7 +74,7 @@ gcode: # We then compute the height to width ratio and validate that the prime line will not be too thin {% if (prime_line_height / line_width) >= 0.5 %} # TODO: validate this 1/2 ratio is good for all {% if verbose %} - {action_raise_error("The prime line will be too thin and will probably not stick properly to the bed. Increase its purge distance or decrease its length! Aborting...")} + {action_raise_error("The prime line will be too thin and will probably not stick properly to the bed. Increase its purge distance or decrease its length!")} {% endif %} {% endif %} @@ -106,12 +109,10 @@ gcode: # Prime line G92 E0 - {% if prime_line_direction == "X" %} G1 X{prime_line_x + prime_line_way*prime_line_length} E{prime_line_purge_distance} F{speed} {% elif prime_line_direction == "Y" %} G1 Y{prime_line_y + prime_line_way*prime_line_length} E{prime_line_purge_distance} F{speed} - {% else %} { action_respond_error("Prime line direction is not valid. Choose either X or Y in the variables.cfg file!") } {% endif %} @@ -121,6 +122,12 @@ gcode: G1 E-0.2 F2100 G92 E0 G1 Z3 F{Sz} + + # Additional small movement to get out of the line as some slicers directly emmit + # a Z- move as a first step that make the toolhead crash back in the line and get dirty + G91 + G1 X2 Y2 F{St} + G90 # Flushing Klipper's buffer to ensure the primeline sequence is done before continuing M400 @@ -132,4 +139,3 @@ gcode: {% if filament_sensor_enabled and re_enable_filament_sensor %} SET_FILAMENT_SENSOR SENSOR="runout_sensor" ENABLE=1 {% endif %} - \ No newline at end of file From 6dc72d26cd3a4f8dc9bb9d93138bf6994ab80bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Tue, 27 Feb 2024 17:39:13 +0000 Subject: [PATCH 5/5] fixed case where prime line could belong outside the bed --- macros/base/start_print.cfg | 2 +- macros/helpers/prime_line.cfg | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/macros/base/start_print.cfg b/macros/base/start_print.cfg index 29a9a05d1..135a68f7b 100644 --- a/macros/base/start_print.cfg +++ b/macros/base/start_print.cfg @@ -29,7 +29,7 @@ gcode: {% set TOOLS_USED = params.TOOLS_USED|default("")|string %} # Check if MMU gates (used in gcode file) are availables {% set SYNC_MMU_EXTRUDER = params.SYNC_MMU_EXTRUDER|default(0)|int %} # set MMU gear motor and extruder synchronization during print TODO {% set BED_MESH_PROFILE = params.MESH|default("")|string %} # Bed mesh profile to load - {% set ADAPTIVE_PRIMELINE = params.ADAPTIVE_PRIMELINE|default(True) %} # Weither to do or not an adaptive prime line near the real print zone + {% set ADAPTIVE_PRIMELINE = params.ADAPTIVE_PRIMELINE|default(1)|int %} # Weither to do or not an adaptive prime line near the real print zone # Set the variables to be used in all the modules based on the slicer parameters SET_GCODE_VARIABLE MACRO=START_PRINT VARIABLE=bed_temp VALUE={BED_TEMP} diff --git a/macros/helpers/prime_line.cfg b/macros/helpers/prime_line.cfg index 9e32011ba..549a56914 100644 --- a/macros/helpers/prime_line.cfg +++ b/macros/helpers/prime_line.cfg @@ -5,7 +5,8 @@ gcode: {% set prime_line_purge_distance = params.PURGE_LENGTH|default(printer["gcode_macro _USER_VARIABLES"].prime_line_purge_distance)|float %} {% set prime_line_flowrate = params.FLOWRATE|default(printer["gcode_macro _USER_VARIABLES"].prime_line_flowrate)|float %} {% set prime_line_height = params.LINE_HEIGHT|default(printer["gcode_macro _USER_VARIABLES"].prime_line_height)|default(0.6)|float %} - {% set prime_line_adaptive = params.ADAPTIVE_MODE|default(True) %} + {% set prime_line_adaptive = params.ADAPTIVE_MODE|default(1)|int %} + {% set prime_line_margin = params.LINE_MARGIN|default(printer["gcode_macro _USER_VARIABLES"].prime_line_margin)|default(5.0)|float %} # Used only in adaptive mode # If the SIZE parameter is defined and not a dummy placeholder, we use it to do the adaptive bed mesh logic {% set coordinatesFound = false %} @@ -31,16 +32,22 @@ gcode: {% set prime_line_y = params.START_Y|default(prime_line_y)|float %} {% set prime_line_direction = params.LINE_DIRECTION|default(printer["gcode_macro _USER_VARIABLES"].prime_line_direction)|string|upper %} - # If first layer is retrieved and adaptive mode is enabled, then we replace the coordinates to do an adaptive purge - {% if coordinatesFound and prime_line_adaptive %} - {% set prime_line_margin = params.LINE_MARGIN|default(printer["gcode_macro _USER_VARIABLES"].prime_line_margin)|default(5.0)|float %} + {% set center_x, center_y = [printer.toolhead.axis_maximum.x / 2, printer.toolhead.axis_maximum.y / 2]|map("float") %} + + # If first layer coordinates are retrieved and adaptive mode is enabled, then we replace the coordinates to + # do an adaptive purge while being careful to have the line stay on the bed when the first layer + # is in an opposite bed quadrant than the prime line initial coordinates (due to mirrored coordinates from center axes)... + {% if coordinatesFound and prime_line_adaptive == 1 %} + {% set prime_line_x = 2*center_x - prime_line_x if (prime_line_x > center_x and xMaxSpec < center_x) or (prime_line_x < center_x and xMinSpec > center_x) + else prime_line_x %} + {% set prime_line_y = 2*center_y - prime_line_y if (prime_line_y > center_y and yMaxSpec < center_y) or (prime_line_y < center_y and yMinSpec > center_y) + else prime_line_y %} {% set prime_line_x = [[prime_line_x, xMinSpec - prime_line_margin]|max, xMaxSpec + prime_line_margin]|min %} {% set prime_line_y = [[prime_line_y, yMinSpec - prime_line_margin]|max, yMaxSpec + prime_line_margin]|min %} {% endif %} # Choose the way of printing the primeline (in + or -) alongside the direction to avoid going outside the bed boundaries - {% set axes_max = printer.toolhead.axis_maximum %} - {% set prime_line_way = -1 if (prime_line_direction == "X" and prime_line_x > axes_max.x/2) or (prime_line_direction == "Y" and prime_line_y > axes_max.y/2) else 1 %} + {% set prime_line_way = -1 if (prime_line_direction == "X" and prime_line_x > center_x) or (prime_line_direction == "Y" and prime_line_y > center_y) else 1 %} {% set St = printer["gcode_macro _USER_VARIABLES"].travel_speed * 60 %} {% set Sz = printer["gcode_macro _USER_VARIABLES"].z_drop_speed * 60 %} @@ -73,9 +80,7 @@ gcode: # We then compute the height to width ratio and validate that the prime line will not be too thin {% if (prime_line_height / line_width) >= 0.5 %} # TODO: validate this 1/2 ratio is good for all - {% if verbose %} - {action_raise_error("The prime line will be too thin and will probably not stick properly to the bed. Increase its purge distance or decrease its length!")} - {% endif %} + {action_raise_error("The prime line will be too thin and will probably not stick properly to the bed. Increase its purge distance or decrease its length!")} {% endif %} # Finally we compute the speed to get the correct flowrate for the prime line