mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-09 06:45:09 -06:00
Merge remote-tracking branch 'origin/master' into WIP_onboarding
This commit is contained in:
commit
6b2642ee9a
59 changed files with 1272 additions and 101 deletions
|
@ -26,6 +26,7 @@ from UM.Preferences import Preferences
|
|||
|
||||
from cura.Machines.VariantType import VariantType
|
||||
from cura.Settings.CuraStackBuilder import CuraStackBuilder
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from cura.Settings.ExtruderStack import ExtruderStack
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
from cura.Settings.CuraContainerStack import _ContainerIndexes
|
||||
|
@ -781,6 +782,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
if not quality_changes_info.extruder_info_dict:
|
||||
container_info = ContainerInfo(None, None, None)
|
||||
quality_changes_info.extruder_info_dict["0"] = container_info
|
||||
# If the global stack we're "targeting" has never been active, but was updated from Cura 3.4,
|
||||
# it might not have it's extruders set properly.
|
||||
if not global_stack.extruders:
|
||||
ExtruderManager.getInstance().fixSingleExtrusionMachineExtruderDefinition(global_stack)
|
||||
extruder_stack = global_stack.extruders["0"]
|
||||
|
||||
container = quality_manager._createQualityChanges(quality_changes_quality_type, quality_changes_name,
|
||||
|
|
|
@ -323,9 +323,10 @@ class StartSliceJob(Job):
|
|||
value = stack.getProperty(key, "value")
|
||||
result[key] = value
|
||||
Job.yieldThread()
|
||||
|
||||
|
||||
result["print_bed_temperature"] = result["material_bed_temperature"] # Renamed settings.
|
||||
result["print_temperature"] = result["material_print_temperature"]
|
||||
result["travel_speed"] = result["speed_travel"]
|
||||
result["time"] = time.strftime("%H:%M:%S") #Some extra settings.
|
||||
result["date"] = time.strftime("%d-%m-%Y")
|
||||
result["day"] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][int(time.strftime("%w"))]
|
||||
|
|
49
plugins/PostProcessingPlugin/scripts/InsertAtLayerChange.py
Normal file
49
plugins/PostProcessingPlugin/scripts/InsertAtLayerChange.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Created by Wayne Porter
|
||||
|
||||
from ..Script import Script
|
||||
|
||||
class InsertAtLayerChange(Script):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def getSettingDataString(self):
|
||||
return """{
|
||||
"name": "Insert at layer change",
|
||||
"key": "InsertAtLayerChange",
|
||||
"metadata": {},
|
||||
"version": 2,
|
||||
"settings":
|
||||
{
|
||||
"insert_location":
|
||||
{
|
||||
"label": "When to insert",
|
||||
"description": "Whether to insert code before or after layer change.",
|
||||
"type": "enum",
|
||||
"options": {"before": "Before", "after": "After"},
|
||||
"default_value": "before"
|
||||
},
|
||||
"gcode_to_add":
|
||||
{
|
||||
"label": "GCODE to insert.",
|
||||
"description": "GCODE to add before or after layer change.",
|
||||
"type": "str",
|
||||
"default_value": ""
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
||||
def execute(self, data):
|
||||
gcode_to_add = self.getSettingValueByKey("gcode_to_add") + "\n"
|
||||
for layer in data:
|
||||
# Check that a layer is being printed
|
||||
lines = layer.split("\n")
|
||||
if ";LAYER:" in lines[0]:
|
||||
index = data.index(layer)
|
||||
if self.getSettingValueByKey("insert_location") == "before":
|
||||
layer = gcode_to_add + layer
|
||||
else:
|
||||
layer = layer + gcode_to_add
|
||||
|
||||
data[index] = layer
|
||||
|
||||
return data
|
94
plugins/PostProcessingPlugin/scripts/TimeLapse.py
Normal file
94
plugins/PostProcessingPlugin/scripts/TimeLapse.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
# Created by Wayne Porter
|
||||
|
||||
from ..Script import Script
|
||||
|
||||
class TimeLapse(Script):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def getSettingDataString(self):
|
||||
return """{
|
||||
"name": "Time Lapse",
|
||||
"key": "TimeLapse",
|
||||
"metadata": {},
|
||||
"version": 2,
|
||||
"settings":
|
||||
{
|
||||
"trigger_command":
|
||||
{
|
||||
"label": "Trigger camera command",
|
||||
"description": "Gcode command used to trigger camera.",
|
||||
"type": "str",
|
||||
"default_value": "M240"
|
||||
},
|
||||
"pause_length":
|
||||
{
|
||||
"label": "Pause length",
|
||||
"description": "How long to wait (in ms) after camera was triggered.",
|
||||
"type": "int",
|
||||
"default_value": 700,
|
||||
"minimum_value": 0,
|
||||
"unit": "ms"
|
||||
},
|
||||
"park_print_head":
|
||||
{
|
||||
"label": "Park Print Head",
|
||||
"description": "Park the print head out of the way. Assumes absolute positioning.",
|
||||
"type": "bool",
|
||||
"default_value": true
|
||||
},
|
||||
"head_park_x":
|
||||
{
|
||||
"label": "Park Print Head X",
|
||||
"description": "What X location does the head move to for photo.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0,
|
||||
"enabled": "park_print_head"
|
||||
},
|
||||
"head_park_y":
|
||||
{
|
||||
"label": "Park Print Head Y",
|
||||
"description": "What Y location does the head move to for photo.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 190,
|
||||
"enabled": "park_print_head"
|
||||
},
|
||||
"park_feed_rate":
|
||||
{
|
||||
"label": "Park Feed Rate",
|
||||
"description": "How fast does the head move to the park coordinates.",
|
||||
"unit": "mm/s",
|
||||
"type": "float",
|
||||
"default_value": 9000,
|
||||
"enabled": "park_print_head"
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
||||
def execute(self, data):
|
||||
feed_rate = self.getSettingValueByKey("park_feed_rate")
|
||||
park_print_head = self.getSettingValueByKey("park_print_head")
|
||||
x_park = self.getSettingValueByKey("head_park_x")
|
||||
y_park = self.getSettingValueByKey("head_park_y")
|
||||
trigger_command = self.getSettingValueByKey("trigger_command")
|
||||
pause_length = self.getSettingValueByKey("pause_length")
|
||||
gcode_to_append = ";TimeLapse Begin\n"
|
||||
|
||||
if park_print_head:
|
||||
gcode_to_append += self.putValue(G = 1, F = feed_rate, X = x_park, Y = y_park) + ";Park print head\n"
|
||||
gcode_to_append += self.putValue(M = 400) + ";Wait for moves to finish\n"
|
||||
gcode_to_append += trigger_command + ";Snap Photo\n"
|
||||
gcode_to_append += self.putValue(G = 4, P = pause_length) + ";Wait for camera\n"
|
||||
gcode_to_append += ";TimeLapse End\n"
|
||||
for layer in data:
|
||||
# Check that a layer is being printed
|
||||
lines = layer.split("\n")
|
||||
if ";LAYER:" in lines[0]:
|
||||
index = data.index(layer)
|
||||
layer += gcode_to_append
|
||||
|
||||
data[index] = layer
|
||||
|
||||
return data
|
|
@ -12,8 +12,10 @@ from UM.Backend.Backend import BackendState
|
|||
from UM.FileHandler.FileHandler import FileHandler
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Qt.Duration import Duration, DurationFormat
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
|
@ -82,8 +84,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
|
|||
self._account = api_client.account
|
||||
|
||||
# We use the Cura Connect monitor tab to get most functionality right away.
|
||||
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
"../../resources/qml/MonitorStage.qml")
|
||||
if PluginRegistry.getInstance() is not None:
|
||||
self._monitor_view_qml_path = os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "qml", "MonitorStage.qml"
|
||||
)
|
||||
|
||||
# Trigger the printersChanged signal when the private signal is triggered.
|
||||
self.printersChanged.connect(self._clusterPrintersChanged)
|
||||
|
|
|
@ -10,13 +10,13 @@ import os
|
|||
|
||||
from UM.FileHandler.FileHandler import FileHandler
|
||||
from UM.FileHandler.WriteFileJob import WriteFileJob # To call the file writer asynchronously.
|
||||
from UM.Logger import Logger
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Qt.Duration import Duration, DurationFormat
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Qt.Duration import Duration, DurationFormat
|
||||
from UM.Scene.SceneNode import SceneNode # For typing.
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||
|
@ -65,7 +65,11 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
self._print_jobs = [] # type: List[UM3PrintJobOutputModel]
|
||||
self._received_print_jobs = False # type: bool
|
||||
|
||||
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorStage.qml")
|
||||
if PluginRegistry.getInstance() is not None:
|
||||
self._monitor_view_qml_path = os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "qml", "MonitorStage.qml"
|
||||
)
|
||||
|
||||
# Trigger the printersChanged signal when the private signal is triggered
|
||||
self.printersChanged.connect(self._clusterPrintersChanged)
|
||||
|
@ -126,8 +130,12 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
|
||||
def _spawnPrinterSelectionDialog(self):
|
||||
if self._printer_selection_dialog is None:
|
||||
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/PrintWindow.qml")
|
||||
self._printer_selection_dialog = self._application.createQmlComponent(path, {"OutputDevice": self})
|
||||
if PluginRegistry.getInstance() is not None:
|
||||
path = os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "qml", "PrintWindow.qml"
|
||||
)
|
||||
self._printer_selection_dialog = self._application.createQmlComponent(path, {"OutputDevice": self})
|
||||
if self._printer_selection_dialog is not None:
|
||||
self._printer_selection_dialog.show()
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from UM.FileHandler.FileHandler import FileHandler
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
|
@ -12,10 +10,13 @@ from cura.PrinterOutputDevice import ConnectionType
|
|||
from cura.Settings.ContainerManager import ContainerManager
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.FileHandler.FileHandler import FileHandler
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
from PyQt5.QtNetwork import QNetworkRequest
|
||||
from PyQt5.QtCore import QTimer, QUrl
|
||||
|
@ -76,7 +77,11 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
|
||||
self.setIconName("print")
|
||||
|
||||
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorItem.qml")
|
||||
if PluginRegistry.getInstance() is not None:
|
||||
self._monitor_view_qml_path = os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "qml", "MonitorStage.qml"
|
||||
)
|
||||
|
||||
self._output_controller = LegacyUM3PrinterOutputController(self)
|
||||
|
||||
|
|
|
@ -14,12 +14,14 @@ from PyQt5.QtGui import QDesktopServices
|
|||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutputDevice import ConnectionType
|
||||
from cura.Settings.GlobalStack import GlobalStack # typing
|
||||
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Signal import Signal, signalemitter
|
||||
from UM.Version import Version
|
||||
from UM.Message import Message
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
from . import ClusterUM3OutputDevice, LegacyUM3OutputDevice
|
||||
from .Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager
|
||||
|
@ -460,8 +462,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self._start_cloud_flow_message = Message(
|
||||
text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."),
|
||||
lifetime = 0,
|
||||
image_source = QUrl.fromLocalFile(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..",
|
||||
"resources", "svg", "cloud-flow-start.svg")),
|
||||
image_source = QUrl.fromLocalFile(os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "svg", "cloud-flow-start.svg"
|
||||
)),
|
||||
image_caption = i18n_catalog.i18nc("@info:status", "Connect to Ultimaker Cloud"),
|
||||
option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."),
|
||||
option_state = False
|
||||
|
@ -482,8 +486,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self._cloud_flow_complete_message = Message(
|
||||
text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."),
|
||||
lifetime = 30,
|
||||
image_source = QUrl.fromLocalFile(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..",
|
||||
"resources", "svg", "cloud-flow-completed.svg")),
|
||||
image_source = QUrl.fromLocalFile(os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "svg", "cloud-flow-completed.svg"
|
||||
)),
|
||||
image_caption = i18n_catalog.i18nc("@info:status", "Connected!")
|
||||
)
|
||||
# Don't show the review connection link if we're not on the local network
|
||||
|
|
|
@ -243,7 +243,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
self._last_temperature_request = time()
|
||||
|
||||
if re.search(b"[B|T\d*]: ?\d+\.?\d*", line): # Temperature message. 'T:' for extruder and 'B:' for bed
|
||||
extruder_temperature_matches = re.findall(b"T(\d*): ?(\d+\.?\d*) ?\/?(\d+\.?\d*)?", line)
|
||||
extruder_temperature_matches = re.findall(b"T(\d*): ?(\d+\.?\d*)\s*\/?(\d+\.?\d*)?", line)
|
||||
# Update all temperature values
|
||||
matched_extruder_nrs = []
|
||||
for match in extruder_temperature_matches:
|
||||
|
@ -265,7 +265,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
if match[2]:
|
||||
extruder.updateTargetHotendTemperature(float(match[2]))
|
||||
|
||||
bed_temperature_matches = re.findall(b"B: ?(\d+\.?\d*) ?\/?(\d+\.?\d*) ?", line)
|
||||
bed_temperature_matches = re.findall(b"B: ?(\d+\.?\d*)\s*\/?(\d+\.?\d*)?", line)
|
||||
if bed_temperature_matches:
|
||||
match = bed_temperature_matches[0]
|
||||
if match[0]:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue