-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into CURA-12081_scarf-seam
- Loading branch information
Showing
7,491 changed files
with
52,371 additions
and
7,586 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
230 changes: 191 additions & 39 deletions
230
plugins/PostProcessingPlugin/scripts/InsertAtLayerChange.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,217 @@ | ||
# Copyright (c) 2020 Ultimaker B.V. | ||
# Cura is released under the terms of the LGPLv3 or higher. | ||
# Created by Wayne Porter | ||
# Re-write in April of 2024 by GregValiant (Greg Foresi) | ||
# Changes: | ||
# Added an 'Enable' setting | ||
# Added support for multi-line insertions (comma delimited) | ||
# Added insertions in a range of layers or a single insertion at a layer. Numbers are consistent with the Cura Preview (base1) | ||
# Added frequency of Insertion (once only, every layer, every 2nd, 3rd, 5th, 10th, 25th, 50th, 100th) | ||
# Added support for 'One at a Time' print sequence | ||
# Rafts are allowed and accounted for but no insertions are made in raft layers | ||
|
||
from ..Script import Script | ||
import re | ||
from UM.Application import Application | ||
|
||
class InsertAtLayerChange(Script): | ||
def __init__(self): | ||
super().__init__() | ||
|
||
def getSettingDataString(self): | ||
return """{ | ||
"name": "Insert at layer change", | ||
"name": "Insert at Layer Change", | ||
"key": "InsertAtLayerChange", | ||
"metadata": {}, | ||
"version": 2, | ||
"settings": | ||
{ | ||
"insert_location": | ||
"enabled": | ||
{ | ||
"label": "When to insert", | ||
"description": "Whether to insert code before or after layer change.", | ||
"label": "Enable this script", | ||
"description": "You must enable the script for it to run.", | ||
"type": "bool", | ||
"default_value": true, | ||
"enabled": true | ||
}, | ||
"insert_frequency": | ||
{ | ||
"label": "How often to insert", | ||
"description": "Every so many layers starting with the Start Layer OR as single insertion at a specific layer. If the print sequence is 'one_at_a_time' then the insertions will be made for every model. Insertions are made at the beginning of a layer.", | ||
"type": "enum", | ||
"options": {"before": "Before", "after": "After"}, | ||
"default_value": "before" | ||
"options": { | ||
"once_only": "One insertion only", | ||
"every_layer": "Every Layer", | ||
"every_2nd": "Every 2nd", | ||
"every_3rd": "Every 3rd", | ||
"every_5th": "Every 5th", | ||
"every_10th": "Every 10th", | ||
"every_25th": "Every 25th", | ||
"every_50th": "Every 50th", | ||
"every_100th": "Every 100th"}, | ||
"default_value": "every_layer", | ||
"enabled": "enabled" | ||
}, | ||
"gcode_to_add": | ||
"start_layer": | ||
{ | ||
"label": "G-code to insert", | ||
"description": "G-code to add before or after layer change.", | ||
"type": "str", | ||
"default_value": "" | ||
"label": "Starting Layer", | ||
"description": "The layer before which the first insertion will take place. If the Print_Sequence is 'All at Once' then use the layer numbers from the Cura Preview. Enter '1' to start at gcode LAYER:0. In 'One at a Time' mode use the layer numbers from the first model that prints AND all models will receive the same insertions. NOTE: There is never an insertion for raft layers.", | ||
"type": "int", | ||
"default_value": 1, | ||
"minimum_value": 1, | ||
"enabled": "insert_frequency != 'once_only' and enabled" | ||
}, | ||
"skip_layers": | ||
"end_layer": | ||
{ | ||
"label": "Skip layers", | ||
"description": "Number of layers to skip between insertions (0 for every layer).", | ||
"label": "Ending Layer", | ||
"description": "The layer before which the last insertion will take place. Enter '-1' to indicate the entire file. Use layer numbers from the Cura Preview.", | ||
"type": "int", | ||
"default_value": 0, | ||
"minimum_value": 0 | ||
"default_value": -1, | ||
"minimum_value": -1, | ||
"enabled": "insert_frequency != 'once_only' and enabled" | ||
}, | ||
"single_end_layer": | ||
{ | ||
"label": "Layer # for Single Insertion.", | ||
"description": "The layer before which the Gcode insertion will take place. Use the layer numbers from the Cura Preview.", | ||
"type": "str", | ||
"default_value": "", | ||
"enabled": "insert_frequency == 'once_only' and enabled" | ||
}, | ||
"gcode_to_add": | ||
{ | ||
"label": "G-code to insert.", | ||
"description": "G-code to add at start of the layer. Use a comma to delimit multi-line commands. EX: G28 X Y,M220 S100,M117 HELL0. NOTE: All inserted text will be converted to upper-case as some firmwares don't understand lower-case.", | ||
"type": "str", | ||
"default_value": "", | ||
"enabled": "enabled" | ||
} | ||
} | ||
}""" | ||
|
||
def execute(self, data): | ||
gcode_to_add = self.getSettingValueByKey("gcode_to_add") + "\n" | ||
skip_layers = self.getSettingValueByKey("skip_layers") | ||
count = 0 | ||
for layer in data: | ||
# Check that a layer is being printed | ||
lines = layer.split("\n") | ||
for line in lines: | ||
if ";LAYER:" in line: | ||
index = data.index(layer) | ||
if count == 0: | ||
if self.getSettingValueByKey("insert_location") == "before": | ||
layer = gcode_to_add + layer | ||
else: | ||
layer = layer + gcode_to_add | ||
|
||
data[index] = layer | ||
|
||
count = (count + 1) % (skip_layers + 1) | ||
break | ||
return data | ||
# Exit if the script is not enabled | ||
if not bool(self.getSettingValueByKey("enabled")): | ||
return data | ||
#Initialize variables | ||
mycode = self.getSettingValueByKey("gcode_to_add").upper() | ||
start_layer = int(self.getSettingValueByKey("start_layer")) | ||
end_layer = int(self.getSettingValueByKey("end_layer")) | ||
when_to_insert = self.getSettingValueByKey("insert_frequency") | ||
end_list = [0] | ||
print_sequence = Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") | ||
# Get the topmost layer number and adjust the end_list | ||
if end_layer == -1: | ||
if print_sequence == "all_at_once": | ||
for lnum in range(0, len(data) - 1): | ||
if ";LAYER:" in data[lnum]: | ||
the_top = int(data[lnum].split(";LAYER:")[1].split("\n")[0]) | ||
end_list[0] = the_top | ||
# Get the topmost layer number for each model and append it to the end_list | ||
if print_sequence == "one_at_a_time": | ||
for lnum in range(0, 10): | ||
if ";LAYER:0" in data[lnum]: | ||
start_at = lnum + 1 | ||
break | ||
for lnum in range(start_at, len(data)-1, 1): | ||
if ";LAYER:" in data[lnum] and not ";LAYER:0" in data[lnum] and not ";LAYER:-" in data[lnum]: | ||
end_list[len(end_list) - 1] = int(data[lnum].split(";LAYER:")[1].split("\n")[0]) | ||
continue | ||
if ";LAYER:0" in data[lnum]: | ||
end_list.append(0) | ||
elif end_layer != -1: | ||
if print_sequence == "all_at_once": | ||
# Catch an error if the entered End_Layer > the top layer in the gcode | ||
for e_num, layer in enumerate(data): | ||
if ";LAYER:" in layer: | ||
top_layer = int(data[e_num].split(";LAYER:")[1].split("\n")[0]) | ||
end_list[0] = end_layer - 1 | ||
if top_layer < end_layer - 1: | ||
end_list[0] = top_layer | ||
elif print_sequence == "one_at_a_time": | ||
# Find the index of the first Layer:0 | ||
for lnum in range(0, 10): | ||
if ";LAYER:0" in data[lnum]: | ||
start_at = lnum + 1 | ||
break | ||
# Get the top layer number for each model | ||
for lnum in range(start_at, len(data)-1): | ||
if ";LAYER:" in data[lnum] and not ";LAYER:0" in data[lnum] and not ";LAYER:-" in data[lnum]: | ||
end_list[len(end_list) - 1] = int(data[lnum].split(";LAYER:")[1].split("\n")[0]) | ||
if ";LAYER:0" in data[lnum]: | ||
end_list.append(0) | ||
# Adjust the end list if an end layer was named | ||
for index, num in enumerate(end_list): | ||
if num > end_layer - 1: | ||
end_list[index] = end_layer - 1 | ||
#If the gcode_to_enter is multi-line then replace the commas with newline characters | ||
if mycode != "": | ||
if "," in mycode: | ||
mycode = re.sub(",", "\n",mycode) | ||
gcode_to_add = mycode | ||
#Get the insertion frequency | ||
match when_to_insert: | ||
case "every_layer": | ||
freq = 1 | ||
case "every_2nd": | ||
freq = 2 | ||
case "every_3rd": | ||
freq = 3 | ||
case "every_5th": | ||
freq = 5 | ||
case "every_10th": | ||
freq = 10 | ||
case "every_25th": | ||
freq = 25 | ||
case "every_50th": | ||
freq = 50 | ||
case "every_100th": | ||
freq = 100 | ||
case "once_only": | ||
the_insert_layer = int(self.getSettingValueByKey("single_end_layer"))-1 | ||
case _: | ||
raise ValueError(f"Unexpected insertion frequency {when_to_insert}") | ||
#Single insertion | ||
if when_to_insert == "once_only": | ||
# For print sequence 'All at once' | ||
if print_sequence == "all_at_once": | ||
for index, layer in enumerate(data): | ||
if ";LAYER:" + str(the_insert_layer) + "\n" in layer: | ||
lines = layer.split("\n") | ||
lines.insert(1,gcode_to_add) | ||
data[index] = "\n".join(lines) | ||
return data | ||
# For print sequence 'One at a time' | ||
else: | ||
for index, layer in enumerate(data): | ||
if ";LAYER:" + str(the_insert_layer) + "\n" in layer: | ||
lines = layer.split("\n") | ||
lines.insert(1,gcode_to_add) | ||
data[index] = "\n".join(lines) | ||
return data | ||
# For multiple insertions | ||
if when_to_insert != "once_only": | ||
# Search from the line after the first Layer:0 so we know when a model ends if in One at a Time mode. | ||
first_0 = True | ||
next_layer = start_layer - 1 | ||
end_layer = end_list.pop(0) | ||
for index, layer in enumerate(data): | ||
lines = layer.split("\n") | ||
for l_index, line in enumerate(lines): | ||
if ";LAYER:" in line: | ||
layer_number = int(line.split(":")[1]) | ||
if layer_number == next_layer and layer_number <= end_layer: | ||
lines.insert(l_index + 1,gcode_to_add) | ||
data[index] = "\n".join(lines) | ||
next_layer += freq | ||
# Reset the next_layer for one-at-a-time | ||
if next_layer > int(end_layer): | ||
next_layer = start_layer - 1 | ||
# Index to the next end_layer when a Layer:0 is encountered | ||
try: | ||
if not first_0 and layer_number == 0: | ||
end_layer = end_list.pop(0) | ||
except: | ||
pass | ||
# Beyond the initial Layer:0 futher Layer:0's indicate the top layer of a model. | ||
if layer_number == 0: | ||
first_0 = False | ||
break | ||
return data |
Oops, something went wrong.