mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-06 14:37:29 -06:00
Merge branch 'master' into feature_unify_pause_at_height
# Conflicts: # plugins/PostProcessingPlugin/scripts/BQ_PauseAtHeight.py
This commit is contained in:
commit
172e6a0759
2596 changed files with 344277 additions and 557779 deletions
|
@ -16,7 +16,7 @@ from UM.Extension import Extension
|
|||
from UM.Logger import Logger
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Resources import Resources
|
||||
from UM.Trust import Trust
|
||||
from UM.Trust import Trust, TrustBasics
|
||||
from UM.i18n import i18nCatalog
|
||||
from cura import ApplicationMetadata
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
@ -156,6 +156,23 @@ class PostProcessingPlugin(QObject, Extension):
|
|||
# This should probably only be done on init.
|
||||
# \param path Path to check for scripts.
|
||||
def loadScripts(self, path: str) -> None:
|
||||
|
||||
if ApplicationMetadata.IsEnterpriseVersion:
|
||||
# Delete all __pycache__ not in installation folder, as it may present a security risk.
|
||||
# It prevents this very strange scenario (should already be prevented on enterprise because signed-fault):
|
||||
# - Copy an existing script from the postprocessing-script folder to the appdata scripts folder.
|
||||
# - Also copy the entire __pycache__ folder from the first to the last location.
|
||||
# - Leave the __pycache__ as is, but write malicious code just before the class begins.
|
||||
# - It'll execute, despite that the script has not been signed.
|
||||
# It's not known if these reproduction steps are minimal, but it does at least happen in this case.
|
||||
install_prefix = os.path.abspath(CuraApplication.getInstance().getInstallPrefix())
|
||||
try:
|
||||
is_in_installation_path = os.path.commonpath([install_prefix, path]).startswith(install_prefix)
|
||||
except ValueError:
|
||||
is_in_installation_path = False
|
||||
if not is_in_installation_path:
|
||||
TrustBasics.removeCached(path)
|
||||
|
||||
## Load all scripts in the scripts folders
|
||||
scripts = pkgutil.iter_modules(path = [path])
|
||||
for loader, script_name, ispkg in scripts:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Post Processing",
|
||||
"author": "Ultimaker",
|
||||
"version": "2.2.1",
|
||||
"api": "7.1",
|
||||
"api": "7.2.0",
|
||||
"description": "Extension that allows for user created scripts for post processing",
|
||||
"catalog": "cura"
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -170,7 +170,7 @@ class ColorMix(Script):
|
|||
modelNumber = 0
|
||||
for active_layer in data:
|
||||
modified_gcode = ""
|
||||
lineIndex = 0;
|
||||
lineIndex = 0
|
||||
lines = active_layer.split("\n")
|
||||
for line in lines:
|
||||
#dont leave blanks
|
||||
|
|
|
@ -132,13 +132,12 @@ class PauseAtHeight(Script):
|
|||
"default_value": 3.3333,
|
||||
"enabled": "pause_method not in [\\\"griffin\\\", \\\"repetier\\\"]"
|
||||
},
|
||||
"redo_layers":
|
||||
"redo_layer":
|
||||
{
|
||||
"label": "Redo Layers",
|
||||
"description": "Redo a number of previous layers after a pause to increases adhesion.",
|
||||
"unit": "layers",
|
||||
"type": "int",
|
||||
"default_value": 0
|
||||
"label": "Redo Layer",
|
||||
"description": "Redo the last layer before the pause, to get the filament flowing again after having oozed a bit during the pause.",
|
||||
"type": "bool",
|
||||
"default_value": false
|
||||
},
|
||||
"standby_temperature":
|
||||
{
|
||||
|
@ -226,7 +225,7 @@ class PauseAtHeight(Script):
|
|||
park_y = self.getSettingValueByKey("head_park_y")
|
||||
move_z = self.getSettingValueByKey("head_move_z")
|
||||
layers_started = False
|
||||
redo_layers = self.getSettingValueByKey("redo_layers")
|
||||
redo_layer = self.getSettingValueByKey("redo_layer")
|
||||
standby_temperature = self.getSettingValueByKey("standby_temperature")
|
||||
firmware_retract = Application.getInstance().getGlobalContainerStack().getProperty("machine_firmware_retract", "value")
|
||||
control_temperatures = Application.getInstance().getGlobalContainerStack().getProperty("machine_nozzle_temp_enabled", "value")
|
||||
|
@ -335,24 +334,23 @@ class PauseAtHeight(Script):
|
|||
if current_e >= 0:
|
||||
break
|
||||
|
||||
# include a number of previous layers
|
||||
for i in range(1, redo_layers + 1):
|
||||
prev_layer = data[index - i]
|
||||
# Maybe redo the last layer.
|
||||
if redo_layer:
|
||||
prev_layer = data[index - 1]
|
||||
layer = prev_layer + layer
|
||||
|
||||
# Get extruder's absolute position at the
|
||||
# beginning of the first layer redone
|
||||
# beginning of the redone layer.
|
||||
# see https://github.com/nallath/PostProcessingPlugin/issues/55
|
||||
if i == redo_layers:
|
||||
# Get X and Y from the next layer (better position for
|
||||
# the nozzle)
|
||||
x, y = self.getNextXY(layer)
|
||||
prev_lines = prev_layer.split("\n")
|
||||
for lin in prev_lines:
|
||||
new_e = self.getValue(lin, "E", current_e)
|
||||
if new_e != current_e:
|
||||
current_e = new_e
|
||||
break
|
||||
# Get X and Y from the next layer (better position for
|
||||
# the nozzle)
|
||||
x, y = self.getNextXY(layer)
|
||||
prev_lines = prev_layer.split("\n")
|
||||
for lin in prev_lines:
|
||||
new_e = self.getValue(lin, "E", current_e)
|
||||
if new_e != current_e:
|
||||
current_e = new_e
|
||||
break
|
||||
|
||||
prepend_gcode = ";TYPE:CUSTOM\n"
|
||||
prepend_gcode += ";added code by post processing\n"
|
||||
|
@ -481,8 +479,8 @@ class PauseAtHeight(Script):
|
|||
|
||||
prepend_gcode += self.putValue(M = 82) + " ; switch back to absolute E values\n"
|
||||
|
||||
# reset extrude value to pre pause value
|
||||
prepend_gcode += self.putValue(G = 92, E = current_e) + "\n"
|
||||
# reset extrude value to pre pause value
|
||||
prepend_gcode += self.putValue(G = 92, E = current_e) + "\n"
|
||||
|
||||
layer = prepend_gcode + layer
|
||||
|
||||
|
|
|
@ -29,45 +29,52 @@ class RetractContinue(Script):
|
|||
current_e = 0
|
||||
current_x = 0
|
||||
current_y = 0
|
||||
current_z = 0
|
||||
extra_retraction_speed = self.getSettingValueByKey("extra_retraction_speed")
|
||||
|
||||
for layer_number, layer in enumerate(data):
|
||||
lines = layer.split("\n")
|
||||
for line_number, line in enumerate(lines):
|
||||
if self.getValue(line, "G") in {0, 1}: # Track X,Y location.
|
||||
if self.getValue(line, "G") in {0, 1}: # Track X,Y,Z location.
|
||||
current_x = self.getValue(line, "X", current_x)
|
||||
current_y = self.getValue(line, "Y", current_y)
|
||||
current_z = self.getValue(line, "Z", current_z)
|
||||
if self.getValue(line, "G") == 1:
|
||||
if self.getValue(line, "E"):
|
||||
new_e = self.getValue(line, "E")
|
||||
if new_e >= current_e: # Not a retraction.
|
||||
continue
|
||||
# A retracted travel move may consist of multiple commands, due to combing.
|
||||
# This continues retracting over all of these moves and only unretracts at the end.
|
||||
delta_line = 1
|
||||
dx = current_x # Track the difference in X for this move only to compute the length of the travel.
|
||||
dy = current_y
|
||||
while line_number + delta_line < len(lines) and self.getValue(lines[line_number + delta_line], "G") != 1:
|
||||
travel_move = lines[line_number + delta_line]
|
||||
if self.getValue(travel_move, "G") != 0:
|
||||
delta_line += 1
|
||||
continue
|
||||
travel_x = self.getValue(travel_move, "X", dx)
|
||||
travel_y = self.getValue(travel_move, "Y", dy)
|
||||
f = self.getValue(travel_move, "F", "no f")
|
||||
length = math.sqrt((travel_x - dx) * (travel_x - dx) + (travel_y - dy) * (travel_y - dy)) # Length of the travel move.
|
||||
new_e -= length * extra_retraction_speed # New retraction is by ratio of this travel move.
|
||||
if f == "no f":
|
||||
new_travel_move = "G1 X{travel_x} Y{travel_y} E{new_e}".format(travel_x = travel_x, travel_y = travel_y, new_e = new_e)
|
||||
else:
|
||||
new_travel_move = "G1 F{f} X{travel_x} Y{travel_y} E{new_e}".format(f = f, travel_x = travel_x, travel_y = travel_y, new_e = new_e)
|
||||
lines[line_number + delta_line] = new_travel_move
|
||||
|
||||
delta_line += 1
|
||||
dx = travel_x
|
||||
dy = travel_y
|
||||
|
||||
if not self.getValue(line, "E"): # Either None or 0: Not a retraction then.
|
||||
continue
|
||||
new_e = self.getValue(line, "E")
|
||||
if new_e - current_e >= -0.0001: # Not a retraction. Account for floating point rounding errors.
|
||||
current_e = new_e
|
||||
continue
|
||||
# A retracted travel move may consist of multiple commands, due to combing.
|
||||
# This continues retracting over all of these moves and only unretracts at the end.
|
||||
delta_line = 1
|
||||
dx = current_x # Track the difference in X for this move only to compute the length of the travel.
|
||||
dy = current_y
|
||||
dz = current_z
|
||||
while line_number + delta_line < len(lines) and self.getValue(lines[line_number + delta_line], "G") != 1:
|
||||
travel_move = lines[line_number + delta_line]
|
||||
if self.getValue(travel_move, "G") != 0:
|
||||
delta_line += 1
|
||||
continue
|
||||
travel_x = self.getValue(travel_move, "X", dx)
|
||||
travel_y = self.getValue(travel_move, "Y", dy)
|
||||
travel_z = self.getValue(travel_move, "Z", dz)
|
||||
f = self.getValue(travel_move, "F", "no f")
|
||||
length = math.sqrt((travel_x - dx) * (travel_x - dx) + (travel_y - dy) * (travel_y - dy) + (travel_z - dz) * (travel_z - dz)) # Length of the travel move.
|
||||
new_e -= length * extra_retraction_speed # New retraction is by ratio of this travel move.
|
||||
if f == "no f":
|
||||
new_travel_move = "G1 X{travel_x} Y{travel_y} Z{travel_z} E{new_e}".format(travel_x = travel_x, travel_y = travel_y, travel_z = travel_z, new_e = new_e)
|
||||
else:
|
||||
new_travel_move = "G1 F{f} X{travel_x} Y{travel_y} Z{travel_z} E{new_e}".format(f = f, travel_x = travel_x, travel_y = travel_y, travel_z = travel_z, new_e = new_e)
|
||||
lines[line_number + delta_line] = new_travel_move
|
||||
|
||||
delta_line += 1
|
||||
dx = travel_x
|
||||
dy = travel_y
|
||||
dz = travel_z
|
||||
|
||||
current_e = new_e
|
||||
|
||||
new_layer = "\n".join(lines)
|
||||
data[layer_number] = new_layer
|
||||
|
|
|
@ -10,10 +10,10 @@ WARNING This script has never been tested with several extruders
|
|||
from ..Script import Script
|
||||
import numpy as np
|
||||
from UM.Logger import Logger
|
||||
from UM.Application import Application
|
||||
import re
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
|
||||
def _getValue(line, key, default=None):
|
||||
"""
|
||||
Convenience function that finds the value in a line of g-code.
|
||||
|
@ -30,6 +30,7 @@ def _getValue(line, key, default=None):
|
|||
return default
|
||||
return float(number.group(0))
|
||||
|
||||
|
||||
class GCodeStep():
|
||||
"""
|
||||
Class to store the current value of each G_Code parameter
|
||||
|
@ -85,7 +86,7 @@ class GCodeStep():
|
|||
|
||||
|
||||
# Execution part of the stretch plugin
|
||||
class Stretcher():
|
||||
class Stretcher:
|
||||
"""
|
||||
Execution part of the stretch algorithm
|
||||
"""
|
||||
|
@ -207,7 +208,6 @@ class Stretcher():
|
|||
return False
|
||||
return True # New sequence
|
||||
|
||||
|
||||
def processLayer(self, layer_steps):
|
||||
"""
|
||||
Computes the new coordinates of g-code steps
|
||||
|
@ -291,7 +291,6 @@ class Stretcher():
|
|||
else:
|
||||
self.layergcode = self.layergcode + layer_steps[i].comment + "\n"
|
||||
|
||||
|
||||
def workOnSequence(self, orig_seq, modif_seq):
|
||||
"""
|
||||
Computes new coordinates for a sequence
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue