diff options
author | Lipu Fei <lipu.fei815@gmail.com> | 2018-07-10 15:57:46 +0300 |
---|---|---|
committer | Lipu Fei <lipu.fei815@gmail.com> | 2018-07-10 15:57:46 +0300 |
commit | 328fd9081e540f3895e1a3a614cc2843e2786830 (patch) | |
tree | ab98846f72ea27df4dfe63ca10d6ad6ba61aae20 /plugins | |
parent | cc5f35dd9181d6a951deeb2e2b007314df3705e3 (diff) | |
parent | f0ef236df083af3f6900e08d821ad70bd808a24d (diff) |
Merge remote-tracking branch 'origin/master' into remove-package-check
Diffstat (limited to 'plugins')
-rwxr-xr-x | plugins/3MFReader/ThreeMFReader.py | 2 | ||||
-rwxr-xr-x | plugins/ChangeLogPlugin/ChangeLog.txt | 7 | ||||
-rwxr-xr-x | plugins/CuraEngineBackend/CuraEngineBackend.py | 64 | ||||
-rw-r--r-- | plugins/CuraEngineBackend/StartSliceJob.py | 13 | ||||
-rw-r--r-- | plugins/GCodeReader/FlavorParser.py | 1 | ||||
-rw-r--r-- | plugins/PostProcessingPlugin/scripts/PauseAtHeight.py | 12 | ||||
-rw-r--r-- | plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py | 6 | ||||
-rwxr-xr-x | plugins/SliceInfoPlugin/SliceInfo.py | 15 | ||||
-rw-r--r-- | plugins/Toolbox/src/Toolbox.py | 5 | ||||
-rw-r--r-- | plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py | 17 | ||||
-rw-r--r-- | plugins/UM3NetworkPrinting/DiscoverUM3Action.py | 2 | ||||
-rw-r--r-- | plugins/USBPrinting/USBPrinterOutputDevice.py | 2 | ||||
-rw-r--r-- | plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py | 2 |
13 files changed, 94 insertions, 54 deletions
diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 6bfe920863..0280600834 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -169,8 +169,6 @@ class ThreeMFReader(MeshReader): archive = zipfile.ZipFile(file_name, "r") self._base_name = os.path.basename(file_name) parser = Savitar.ThreeMFParser() - with open("/tmp/test.xml", "wb") as f: - f.write(archive.open("3D/3dmodel.model").read()) scene_3mf = parser.parse(archive.open("3D/3dmodel.model").read()) self._unit = scene_3mf.getUnit() for node in scene_3mf.getSceneNodes(): diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index 8da415df05..aefeb92ce5 100755 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -1,4 +1,9 @@ - +[3.4.1] +*Bug fixes +- Fixed an issue that would occasionally cause an unnecessary extra skin wall to be printed, which increased print time. +- Fixed an issue in which supports were not generated on the initial layer, because the engine expected a brim to be in place. +- Conical and tree supports are now limited within the build plate volume. +- Fixed various startup crashes, including: copying of the version folder, errors while deleting packages, storing the old files, and losing data on install. [3.4.0] diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index e7dca2ae3e..2b3c2b29f8 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -21,6 +21,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.SettingInstance import SettingInstance #For typing. from UM.Tool import Tool #For typing. +from UM.Mesh.MeshData import MeshData #For typing. from cura.CuraApplication import CuraApplication from cura.Settings.ExtruderManager import ExtruderManager @@ -62,15 +63,15 @@ class CuraEngineBackend(QObject, Backend): if Platform.isLinux() and not default_engine_location: if not os.getenv("PATH"): raise OSError("There is something wrong with your Linux installation.") - for pathdir in os.getenv("PATH").split(os.pathsep): + for pathdir in cast(str, os.getenv("PATH")).split(os.pathsep): execpath = os.path.join(pathdir, executable_name) if os.path.exists(execpath): default_engine_location = execpath break self._application = CuraApplication.getInstance() #type: CuraApplication - self._multi_build_plate_model = None #type: MultiBuildPlateModel - self._machine_error_checker = None #type: MachineErrorChecker + self._multi_build_plate_model = None #type: Optional[MultiBuildPlateModel] + self._machine_error_checker = None #type: Optional[MachineErrorChecker] if not default_engine_location: raise EnvironmentError("Could not find CuraEngine") @@ -120,7 +121,7 @@ class CuraEngineBackend(QObject, Backend): self._engine_is_fresh = True #type: bool # Is the newly started engine used before or not? self._backend_log_max_lines = 20000 #type: int # Maximum number of lines to buffer - self._error_message = None #type: Message # Pop-up message that shows errors. + self._error_message = None #type: Optional[Message] # Pop-up message that shows errors. self._last_num_objects = defaultdict(int) #type: Dict[int, int] # Count number of objects to see if there is something changed self._postponed_scene_change_sources = [] #type: List[SceneNode] # scene change is postponed (by a tool) @@ -145,7 +146,9 @@ class CuraEngineBackend(QObject, Backend): self._multi_build_plate_model = self._application.getMultiBuildPlateModel() self._application.getController().activeViewChanged.connect(self._onActiveViewChanged) - self._multi_build_plate_model.activeBuildPlateChanged.connect(self._onActiveViewChanged) + + if self._multi_build_plate_model: + self._multi_build_plate_model.activeBuildPlateChanged.connect(self._onActiveViewChanged) self._application.globalContainerStackChanged.connect(self._onGlobalStackChanged) self._onGlobalStackChanged() @@ -246,7 +249,7 @@ class CuraEngineBackend(QObject, Backend): if self._application.getPrintInformation() and build_plate_to_be_sliced == active_build_plate: self._application.getPrintInformation().setToZeroPrintInformation(build_plate_to_be_sliced) - if self._process is None: + if self._process is None: # type: ignore self._createSocket() self.stopSlicing() self._engine_is_fresh = False # Yes we're going to use the engine @@ -284,12 +287,12 @@ class CuraEngineBackend(QObject, Backend): if self._application.getUseExternalBackend(): return - if self._process is not None: + if self._process is not None: # type: ignore Logger.log("d", "Killing engine process") try: - self._process.terminate() - Logger.log("d", "Engine process is killed. Received return code %s", self._process.wait()) - self._process = None + self._process.terminate() # type: ignore + Logger.log("d", "Engine process is killed. Received return code %s", self._process.wait()) # type: ignore + self._process = None # type: ignore except Exception as e: # terminating a process that is already terminating causes an exception, silently ignore this. Logger.log("d", "Exception occurred while trying to kill the engine %s", str(e)) @@ -328,6 +331,9 @@ class CuraEngineBackend(QObject, Backend): if job.getResult() == StartJobResult.SettingError: if self._application.platformActivity: + if not self._global_container_stack: + Logger.log("w", "Global container stack not assigned to CuraEngineBackend!") + return extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) error_keys = [] #type: List[str] for extruder in extruders: @@ -361,6 +367,9 @@ class CuraEngineBackend(QObject, Backend): if not stack: continue for key in stack.getErrorKeys(): + if not self._global_container_stack: + Logger.log("e", "CuraEngineBackend does not have global_container_stack assigned.") + continue definition = cast(DefinitionContainerInterface, self._global_container_stack.getBottom()).findDefinitions(key = key) if not definition: Logger.log("e", "When checking settings for errors, unable to find definition for key {key} in per-object stack.".format(key = key)) @@ -409,7 +418,8 @@ class CuraEngineBackend(QObject, Backend): # Notify the user that it's now up to the backend to do it's job self.backendStateChange.emit(BackendState.Processing) - Logger.log("d", "Sending slice message took %s seconds", time() - self._slice_start_time ) + if self._slice_start_time: + Logger.log("d", "Sending slice message took %s seconds", time() - self._slice_start_time ) ## Determine enable or disable auto slicing. Return True for enable timer and False otherwise. # It disables when @@ -476,15 +486,12 @@ class CuraEngineBackend(QObject, Backend): else: # we got a single scenenode if not source.callDecoration("isGroup"): - if source.getMeshData() is None: - return - if source.getMeshData().getVertices() is None: + mesh_data = source.getMeshData() + if mesh_data and mesh_data.getVertices() is None: return build_plate_changed.add(source_build_plate_number) - build_plate_changed.discard(None) - build_plate_changed.discard(-1) # object not on build plate if not build_plate_changed: return @@ -577,9 +584,10 @@ class CuraEngineBackend(QObject, Backend): # # \param message The protobuf message containing sliced layer data. def _onOptimizedLayerMessage(self, message: Arcus.PythonMessage) -> None: - if self._start_slice_job_build_plate not in self._stored_optimized_layer_data: - self._stored_optimized_layer_data[self._start_slice_job_build_plate] = [] - self._stored_optimized_layer_data[self._start_slice_job_build_plate].append(message) + if self._start_slice_job_build_plate: + if self._start_slice_job_build_plate not in self._stored_optimized_layer_data: + self._stored_optimized_layer_data[self._start_slice_job_build_plate] = [] + self._stored_optimized_layer_data[self._start_slice_job_build_plate].append(message) ## Called when a progress message is received from the engine. # @@ -619,7 +627,8 @@ class CuraEngineBackend(QObject, Backend): gcode_list[index] = replaced self._slicing = False - Logger.log("d", "Slicing took %s seconds", time() - self._slice_start_time ) + if self._slice_start_time: + Logger.log("d", "Slicing took %s seconds", time() - self._slice_start_time ) Logger.log("d", "Number of models per buildplate: %s", dict(self._numObjectsPerBuildPlate())) # See if we need to process the sliced layers job. @@ -658,7 +667,11 @@ class CuraEngineBackend(QObject, Backend): ## Creates a new socket connection. def _createSocket(self, protocol_file: str = None) -> None: if not protocol_file: - protocol_file = os.path.abspath(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "Cura.proto")) + plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) + if not plugin_path: + Logger.log("e", "Could not get plugin path!", self.getPluginId()) + return + protocol_file = os.path.abspath(os.path.join(plugin_path, "Cura.proto")) super()._createSocket(protocol_file) self._engine_is_fresh = True @@ -773,9 +786,9 @@ class CuraEngineBackend(QObject, Backend): # We should reset our state and start listening for new connections. def _onBackendQuit(self) -> None: if not self._restart: - if self._process: - Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait()) - self._process = None + if self._process: # type: ignore + Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait()) # type: ignore + self._process = None # type: ignore ## Called when the global container stack changes def _onGlobalStackChanged(self) -> None: @@ -831,6 +844,9 @@ class CuraEngineBackend(QObject, Backend): self._change_timer.start() def _extruderChanged(self) -> None: + if not self._multi_build_plate_model: + Logger.log("w", "CuraEngineBackend does not have multi_build_plate_model assigned!") + return for build_plate_number in range(self._multi_build_plate_model.maxBuildPlate + 1): if build_plate_number not in self._build_plates_to_be_sliced: self._build_plates_to_be_sliced.append(build_plate_number) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 20c426209f..9a40445a18 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -5,7 +5,7 @@ import numpy from string import Formatter from enum import IntEnum import time -from typing import Any, Dict, List, Optional, Set +from typing import Any, cast, Dict, List, Optional, Set import re import Arcus #For typing. @@ -209,12 +209,15 @@ class StartSliceJob(Job): if temp_list: object_groups.append(temp_list) - extruders_enabled = {position: stack.isEnabled for position, stack in CuraApplication.getInstance().getGlobalContainerStack().extruders.items()} + global_stack = CuraApplication.getInstance().getGlobalContainerStack() + if not global_stack: + return + extruders_enabled = {position: stack.isEnabled for position, stack in global_stack.extruders.items()} filtered_object_groups = [] has_model_with_disabled_extruders = False associated_disabled_extruders = set() for group in object_groups: - stack = CuraApplication.getInstance().getGlobalContainerStack() + stack = global_stack skip_group = False for node in group: extruder_position = node.callDecoration("getActiveExtruderPosition") @@ -227,7 +230,7 @@ class StartSliceJob(Job): if has_model_with_disabled_extruders: self.setResult(StartJobResult.ObjectsWithDisabledExtruder) - associated_disabled_extruders = [str(c) for c in sorted([int(p) + 1 for p in associated_disabled_extruders])] + associated_disabled_extruders = {str(c) for c in sorted([int(p) + 1 for p in associated_disabled_extruders])} self.setMessage(", ".join(associated_disabled_extruders)) return @@ -318,7 +321,7 @@ class StartSliceJob(Job): # \param default_extruder_nr Stack nr to use when no stack nr is specified, defaults to the global stack def _expandGcodeTokens(self, value: str, default_extruder_nr: int = -1) -> str: if not self._all_extruders_settings: - global_stack = CuraApplication.getInstance().getGlobalContainerStack() + global_stack = cast(ContainerStack, CuraApplication.getInstance().getGlobalContainerStack()) # NB: keys must be strings for the string formatter self._all_extruders_settings = { diff --git a/plugins/GCodeReader/FlavorParser.py b/plugins/GCodeReader/FlavorParser.py index 990bd98fb5..10f841fc43 100644 --- a/plugins/GCodeReader/FlavorParser.py +++ b/plugins/GCodeReader/FlavorParser.py @@ -286,6 +286,7 @@ class FlavorParser: self._cancelled = False # We obtain the filament diameter from the selected extruder to calculate line widths global_stack = CuraApplication.getInstance().getGlobalContainerStack() + if not global_stack: return None diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py index 545db24048..6354dd4f04 100644 --- a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py +++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py @@ -266,8 +266,10 @@ class PauseAtHeight(Script): # Retraction prepend_gcode += self.putValue(M = 83) + "\n" if retraction_amount != 0: - if firmware_retract: - prepend_gcode += self.putValue(G = 10) + if firmware_retract: #Can't set the distance directly to what the user wants. We have to choose ourselves. + retraction_count = 1 if control_temperatures else 3 #Retract more if we don't control the temperature. + for i in range(retraction_count): + prepend_gcode += self.putValue(G = 10) + "\n" else: prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = retraction_speed * 60) + "\n" @@ -309,8 +311,10 @@ class PauseAtHeight(Script): prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n" prepend_gcode += self.putValue(G = 1, X = x, Y = y, F = 9000) + "\n" if retraction_amount != 0: - if firmware_retract: - prepend_gcode += self.putValue(G = 11) + if firmware_retract: #Can't set the distance directly to what the user wants. We have to choose ourselves. + retraction_count = 1 if control_temperatures else 3 #Retract more if we don't control the temperature. + for i in range(retraction_count): + prepend_gcode += self.putValue(G = 11) + "\n" else: prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = retraction_speed * 60) + "\n" prepend_gcode += self.putValue(G = 1, F = 9000) + "\n" diff --git a/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py b/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py index 7a3e1ab5c1..51b6a70b7a 100644 --- a/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py +++ b/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py @@ -11,7 +11,7 @@ from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") # Ignore windows error popups. Fixes the whole "Can't open drive X" when user has an SD card reader. -ctypes.windll.kernel32.SetErrorMode(1) +ctypes.windll.kernel32.SetErrorMode(1) #type: ignore # WinAPI Constants that we need # Hardcoded here due to stupid WinDLL stuff that does not give us access to these values. @@ -29,7 +29,7 @@ OPEN_EXISTING = 3 # [CodeStyle: Windows Enum value] # Setup the DeviceIoControl function arguments and return type. # See ctypes documentation for details on how to call C functions from python, and why this is important. -ctypes.windll.kernel32.DeviceIoControl.argtypes = [ +ctypes.windll.kernel32.DeviceIoControl.argtypes = [ #type: ignore wintypes.HANDLE, # _In_ HANDLE hDevice wintypes.DWORD, # _In_ DWORD dwIoControlCode wintypes.LPVOID, # _In_opt_ LPVOID lpInBuffer @@ -39,7 +39,7 @@ ctypes.windll.kernel32.DeviceIoControl.argtypes = [ ctypes.POINTER(wintypes.DWORD), # _Out_opt_ LPDWORD lpBytesReturned wintypes.LPVOID # _Inout_opt_ LPOVERLAPPED lpOverlapped ] -ctypes.windll.kernel32.DeviceIoControl.restype = wintypes.BOOL +ctypes.windll.kernel32.DeviceIoControl.restype = wintypes.BOOL #type: ignore ## Removable drive support for windows diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index fe17af89eb..2e9e557c4a 100755 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -16,7 +16,7 @@ from UM.i18n import i18nCatalog from UM.Logger import Logger from UM.PluginRegistry import PluginRegistry from UM.Qt.Duration import DurationFormat - +from typing import cast, Optional from .SliceInfoJob import SliceInfoJob @@ -79,11 +79,16 @@ class SliceInfo(QObject, Extension): return dialog @pyqtSlot(result = str) - def getExampleData(self) -> str: + def getExampleData(self) -> Optional[str]: if self._example_data_content is None: - file_path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "example_data.json") - with open(file_path, "r", encoding = "utf-8") as f: - self._example_data_content = f.read() + plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) + if not plugin_path: + Logger.log("e", "Could not get plugin path!", self.getPluginId()) + return None + file_path = os.path.join(plugin_path, "example_data.json") + if file_path: + with open(file_path, "r", encoding = "utf-8") as f: + self._example_data_content = f.read() return self._example_data_content @pyqtSlot(bool) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 4e59fcd055..3fec67c96e 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -6,7 +6,7 @@ import json import os import tempfile import platform -from typing import List +from typing import cast, List from PyQt5.QtCore import QUrl, QObject, pyqtProperty, pyqtSignal, pyqtSlot from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply @@ -250,7 +250,10 @@ class Toolbox(QObject, Extension): if not plugin_path: return None path = os.path.join(plugin_path, "resources", "qml", qml_name) + dialog = self._application.createQmlComponent(path, {"toolbox": self}) + if not dialog: + raise Exception("Failed to create toolbox dialog") return dialog def _convertPluginMetadata(self, plugin: Dict[str, Any]) -> Dict[str, Any]: diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index 757ed4ef66..84e0a66170 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Any, cast, Set, Tuple, Union +from typing import Any, cast, Optional, Set, Tuple, Union from UM.FileHandler.FileHandler import FileHandler from UM.FileHandler.FileWriter import FileWriter #To choose based on the output file mode (text vs. binary). @@ -9,6 +9,7 @@ from UM.FileHandler.WriteFileJob import WriteFileJob #To call the file writer as from UM.Logger import Logger from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog +from UM.Mesh.MeshWriter import MeshWriter # For typing from UM.Message import Message from UM.Qt.Duration import Duration, DurationFormat from UM.OutputDevice import OutputDeviceError #To show that something went wrong when writing. @@ -104,10 +105,11 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): file_formats = CuraApplication.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() global_stack = CuraApplication.getInstance().getGlobalContainerStack() + #Create a list from the supported file formats string. if not global_stack: + Logger.log("e", "Missing global stack!") return - #Create a list from the supported file formats string. machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";") machine_file_formats = [file_type.strip() for file_type in machine_file_formats] #Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format. @@ -134,6 +136,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): return #This function pauses with the yield, waiting on instructions on which printer it needs to print with. + if not writer: + Logger.log("e", "Missing file or mesh writer!") + return self._sending_job = self._sendPrintJob(writer, preferred_format, nodes) self._sending_job.send(None) #Start the generator. @@ -213,16 +218,14 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): yield #To prevent having to catch the StopIteration exception. def _sendPrintJobWaitOnWriteJobFinished(self, job: WriteFileJob) -> None: - # This is the callback when the job finishes, where the message is created - assert(self._write_job_progress_message is not None) - self._write_job_progress_message.hide() + if self._write_job_progress_message: + self._write_job_progress_message.hide() self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), lifetime = 0, dismissable = False, progress = -1, title = i18n_catalog.i18nc("@info:title", "Sending Data")) self._progress_message.addAction("Abort", i18n_catalog.i18nc("@action:button", "Cancel"), icon = None, description = "") self._progress_message.actionTriggered.connect(self._progressMessageActionTriggered) self._progress_message.show() - parts = [] target_printer, preferred_format, stream = self._dummy_lambdas @@ -259,7 +262,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self.activePrinterChanged.emit() def _onPostPrintJobFinished(self, reply: QNetworkReply) -> None: - if self._progress_message is not None: + if self._progress_message: self._progress_message.hide() self._compressing_gcode = False self._sending_gcode = False diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py index 3752cc0c25..b48a57e0a2 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py @@ -3,7 +3,7 @@ import os.path import time -from typing import Optional +from typing import cast, Optional from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 69a0ecb40c..f9c6011f7b 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -423,7 +423,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): elapsed_time = int(time() - self._print_start_time) print_job = self._printers[0].activePrintJob if print_job is None: - print_job = PrintJobOutputModel(output_controller = GenericOutputController(self), name= Application.getInstance().getPrintInformation().jobName) + print_job = PrintJobOutputModel(output_controller = GenericOutputController(self), name= CuraApplication.getInstance().getPrintInformation().jobName) print_job.updateState("printing") self._printers[0].updateActivePrintJob(print_job) diff --git a/plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py b/plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py index 2877985921..0cf7ef0cc4 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py +++ b/plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py @@ -71,6 +71,8 @@ class VersionUpgrade34to40(VersionUpgrade): self._resetConcentric3DInfillPattern(parser) if "values" in parser: for deleted_setting in deleted_settings: + if deleted_setting not in parser["values"]: + continue del parser["values"][deleted_setting] result = io.StringIO() |