diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/ConfigurationModel.py new file mode 100644 index 0000000000..bb219a0e2f --- /dev/null +++ b/cura/PrinterOutput/ConfigurationModel.py @@ -0,0 +1,42 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import pyqtProperty, QObject + + +class ConfigurationModel(QObject): + + def __init__(self): + self._printer_type = None + self._extruder_configurations = [] + self._buildplate_configuration = None + + def setPrinterType(self, printer_type): + self._printer_type = printer_type + + @pyqtProperty(str, fset = setPrinterType, constant = True) + def printerType(self): + return self._printer_type + + def setExtruderConfigurations(self, extruder_configurations): + self._extruder_configurations = extruder_configurations + + @pyqtProperty("QVariantList", fset = setExtruderConfigurations, constant = True) + def extruderConfigurations(self): + return self._extruder_configurations + + def setBuildplateConfiguration(self, buildplate_configuration): + self._buildplate_configuration = buildplate_configuration + + @pyqtProperty(str, fset = setBuildplateConfiguration, constant = True) + def buildplateConfiguration(self): + return self._buildplate_configuration + + def __eq__(self, other): + return hash(self) == hash(other) + + def __hash__(self): + extruder_hash = hash(0) + for configuration in self.extruderConfigurations: + extruder_hash ^= hash(frozenset(configuration.items())) + return hash(self.printerType) ^ extruder_hash ^ hash(self.buildplateConfiguration) \ No newline at end of file diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index b0be6cbbe4..33f3bf71f5 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -17,14 +17,20 @@ class ExtruderOutputModel(QObject): targetHotendTemperatureChanged = pyqtSignal() hotendTemperatureChanged = pyqtSignal() activeMaterialChanged = pyqtSignal() + extruderConfigurationChanged = pyqtSignal() - def __init__(self, printer: "PrinterOutputModel", parent=None): + def __init__(self, printer: "PrinterOutputModel", position, parent=None): super().__init__(parent) self._printer = printer + self._position = position self._target_hotend_temperature = 0 self._hotend_temperature = 0 self._hotend_id = "" self._active_material = None # type: Optional[MaterialOutputModel] + self._extruder_configuration = {} + # Update the configuration every time the hotend or the active material change + self.hotendIDChanged.connect(self._updateExtruderConfiguration) + self.activeMaterialChanged.connect(self._updateExtruderConfiguration) @pyqtProperty(QObject, notify = activeMaterialChanged) def activeMaterial(self) -> "MaterialOutputModel": @@ -68,3 +74,16 @@ class ExtruderOutputModel(QObject): if self._hotend_id != id: self._hotend_id = id self.hotendIDChanged.emit() + + @pyqtProperty("QVariantMap", notify = extruderConfigurationChanged) + def extruderConfiguration(self): + return self._extruder_configuration + + def _updateExtruderConfiguration(self): + self._extruder_configuration = { + "position": self._position, + "material": self._active_material.type if self.activeMaterial is not None else None, + "hotend_id": self._hotend_id + } + print("Recalculating extruder configuration:", self._extruder_configuration) + self.extruderConfigurationChanged.emit() diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 01a8203c32..0cdec88194 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -5,6 +5,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot from UM.Logger import Logger from typing import Optional, List from UM.Math.Vector import Vector +from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel MYPY = False @@ -24,6 +25,7 @@ class PrinterOutputModel(QObject): keyChanged = pyqtSignal() typeChanged = pyqtSignal() cameraChanged = pyqtSignal() + configurationChanged = pyqtSignal() def __init__(self, output_controller: "PrinterOutputController", number_of_extruders: int = 1, parent=None, firmware_version = ""): super().__init__(parent) @@ -32,13 +34,17 @@ class PrinterOutputModel(QObject): self._name = "" self._key = "" # Unique identifier self._controller = output_controller - self._extruders = [ExtruderOutputModel(printer=self) for i in range(number_of_extruders)] + self._extruders = [ExtruderOutputModel(printer = self, position = i) for i in range(number_of_extruders)] + self._printer_configuration = ConfigurationModel() # Indicates the current configuration setup in this printer self._head_position = Vector(0, 0, 0) self._active_print_job = None # type: Optional[PrintJobOutputModel] self._firmware_version = firmware_version self._printer_state = "unknown" self._is_preheating = False self._type = "" + # Update the configuration every time the one of the extruders changes its configuration + for extruder in self._extruders: + extruder.extruderConfigurationChanged.connect(self._updatePrinterConfiguration) self._camera = None @@ -238,3 +244,15 @@ class PrinterOutputModel(QObject): if self._controller: return self._controller.can_control_manually return False + + # Returns the configuration (material, variant and buildplate) of the current printer + @pyqtProperty(QObject, notify = configurationChanged) + def printerConfiguration(self): + return self._printer_configuration + + def _updatePrinterConfiguration(self): + self._printer_configuration.printerType = self._type + self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in self._extruders] + self._printer_configuration.buildplateConfiguration = None # TODO Add the buildplate information + print("Recalculating printer configuration", self.name, ":", self._printer_configuration) + self.configurationChanged.emit() diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 9e603b83ae..ac8f317689 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -17,6 +17,7 @@ from typing import List, Optional MYPY = False if MYPY: from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel + from cura.PrinterOutput.ConfigurationModel import ConfigurationModel i18n_catalog = i18nCatalog("cura") @@ -44,10 +45,14 @@ class PrinterOutputDevice(QObject, OutputDevice): # Signal to indicate that the info text about the connection has changed. connectionTextChanged = pyqtSignal() + # Signal to indicate that the configuration of one of the printers has changed. + configurationChanged = pyqtSignal() + def __init__(self, device_id, parent = None): super().__init__(device_id = device_id, parent = parent) self._printers = [] # type: List[PrinterOutputModel] + self._unique_configurations = [] # type: List[ConfigurationModel] self._monitor_view_qml_path = "" self._monitor_component = None @@ -69,6 +74,7 @@ class PrinterOutputDevice(QObject, OutputDevice): self._address = "" self._connection_text = "" + self.printersChanged.connect(self._onPrintersChanged) @pyqtProperty(str, notify = connectionTextChanged) def address(self): @@ -175,6 +181,21 @@ class PrinterOutputDevice(QObject, OutputDevice): self.acceptsCommandsChanged.emit() + # Returns the unique configurations of the current printers + @pyqtProperty("QVariantList", notify = configurationChanged) + def uniqueConfiguration(self): + return self._unique_configurations + + def _updateUniqueConfigurations(self): + print("Calculating the unique configurations") + self._unique_configurations = list(set([printer.printerConfiguration for printer in self._printers])) + print(self._unique_configurations) + self.configurationChanged.emit() + + def _onPrintersChanged(self): + for printer in self._printers: + printer.configurationChanged.connect(self._updateUniqueConfigurations) + ## The current processing state of the backend. class ConnectionState(IntEnum):